summaryrefslogtreecommitdiff
path: root/Source/Plugins
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2012-03-22 15:21:52 +0100
committerPierre Bourdon <delroth@gmail.com>2012-03-22 15:21:52 +0100
commit0ffc12bbfd6ac44b3030ec30f400a58e951087b7 (patch)
tree53a6fac9ec79bcd71fe2046d8fb579478da12fd2 /Source/Plugins
parent006923e871e496a7c6c0fe9ba76da4ee939ce14e (diff)
parentd95e31af3f779bfa3141047e8b6275e1fd2e4bbb (diff)
Merge branch 'master' into zcomploc-support
Conflicts: Source/Core/VideoCommon/Src/PixelShaderGen.cpp
Diffstat (limited to 'Source/Plugins')
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj3
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp2
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp7
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp71
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h12
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp7
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/Render.cpp175
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/Render.h2
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp22
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp7
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp40
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h11
-rw-r--r--Source/Plugins/Plugin_VideoDX11/Src/main.cpp7
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj3
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp19
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h1
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp26
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h4
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp50
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h7
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/Render.cpp129
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/Render.h2
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp42
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp90
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.h6
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp7
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp33
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h9
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/main.cpp3
-rw-r--r--Source/Plugins/Plugin_VideoOGL/CMakeLists.txt4
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj3
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp5
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp48
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h8
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/Render.cpp350
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/Render.h7
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp20
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp86
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h6
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp9
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp38
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h9
-rw-r--r--Source/Plugins/Plugin_VideoOGL/Src/main.cpp1
-rw-r--r--Source/Plugins/Plugin_VideoSoftware/Plugin_VideoSoftware.vcxproj3
-rw-r--r--Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp6
-rw-r--r--Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp6
-rw-r--r--Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h2
47 files changed, 679 insertions, 729 deletions
diff --git a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj
index f1f4d40457..2903bd0550 100644
--- a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj
+++ b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj
@@ -46,7 +46,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -57,7 +57,6 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp
index 81a4cf96a6..8ee8081b2c 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DUtil.cpp
@@ -595,7 +595,7 @@ void drawShadedTexSubQuad(ID3D11ShaderResourceView* texture,
// only upload the data to VRAM if it changed
if (stsq_observer ||
- memcmp(rDest, &tex_sub_quad_data.rdest, sizeof(rDest)) != 0 ||
+ memcmp(rDest, &tex_sub_quad_data.rdest, sizeof(*rDest)) != 0 ||
tex_sub_quad_data.u1 != u1 || tex_sub_quad_data.v1 != v1 ||
tex_sub_quad_data.u2 != u2 || tex_sub_quad_data.v2 != v2 || tex_sub_quad_data.G != G)
{
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp
index 25f3712eb1..3afd38a2e1 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/LineGeometryShader.cpp
@@ -187,14 +187,15 @@ bool LineGeometryShader::SetShader(u32 components, float lineWidth,
p = GenerateVSOutputStruct(p, components, API_D3D11);
p += sprintf(p, "\n%s", LINE_GS_COMMON);
- std::stringstream numTexCoordsStr;
- numTexCoordsStr << xfregs.numTexGen.numTexGens;
+ std::stringstream numTexCoordsStream;
+ numTexCoordsStream << xfregs.numTexGen.numTexGens;
INFO_LOG(VIDEO, "Compiling line geometry shader for components 0x%.08X (num texcoords %d)",
components, xfregs.numTexGen.numTexGens);
+ const std::string& numTexCoordsStr = numTexCoordsStream.str();
D3D_SHADER_MACRO macros[] = {
- { "NUM_TEXCOORDS", numTexCoordsStr.str().c_str() },
+ { "NUM_TEXCOORDS", numTexCoordsStr.c_str() },
{ NULL, NULL }
};
ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros);
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp
index 5418923bf8..fe33c4db80 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp
@@ -41,6 +41,7 @@ namespace DX11
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
const PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry;
+PIXELSHADERUID PixelShaderCache::last_uid;
LinearDiskCache<PIXELSHADERUID, u8> g_ps_disk_cache;
@@ -412,6 +413,11 @@ void PixelShaderCache::Init()
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
PixelShaderCacheInserter inserter;
g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
+
+ if (g_Config.bEnableShaderDebugging)
+ Clear();
+
+ last_entry = NULL;
}
// ONLY to be used during shutdown.
@@ -420,6 +426,8 @@ void PixelShaderCache::Clear()
for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++)
iter->second.Destroy();
PixelShaders.clear();
+
+ last_entry = NULL;
}
// Used in Swap() when AA mode has changed
@@ -454,28 +462,31 @@ void PixelShaderCache::Shutdown()
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
{
PIXELSHADERUID uid;
- GetPixelShaderId(&uid, dstAlphaMode);
+ GetPixelShaderId(&uid, dstAlphaMode, components);
// Check if the shader is already set
- if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
+ if (last_entry)
{
- PSCache::const_iterator iter = PixelShaders.find(uid);
- GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
- return (iter != PixelShaders.end() && iter->second.shader);
+ if (uid == last_uid)
+ {
+ GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
+ ValidatePixelShaderIDs(API_D3D11, last_entry->safe_uid, last_entry->code, dstAlphaMode, components);
+ return (last_entry->shader != NULL);
+ }
}
- memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
+ last_uid = uid;
// Check if the shader is already in the cache
PSCache::iterator iter;
iter = PixelShaders.find(uid);
if (iter != PixelShaders.end())
{
- iter->second.frameCount = frameCount;
const PSCacheEntry &entry = iter->second;
last_entry = &entry;
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
+ ValidatePixelShaderIDs(API_D3D11, entry.safe_uid, entry.code, dstAlphaMode, components);
return (entry.shader != NULL);
}
@@ -485,36 +496,38 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
D3DBlob* pbytecode;
if (!D3D::CompilePixelShader(code, (unsigned int)strlen(code), &pbytecode))
{
- PanicAlert("Failed to compile Pixel Shader:\n\n%s", code);
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
return false;
}
// Insert the bytecode into the caches
g_ps_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size());
- g_ps_disk_cache.Sync();
- bool result = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size());
+ bool success = InsertByteCode(uid, pbytecode->Data(), pbytecode->Size());
pbytecode->Release();
+
+ if (g_ActiveConfig.bEnableShaderDebugging && success)
+ {
+ PixelShaders[uid].code = code;
+ GetSafePixelShaderId(&PixelShaders[uid].safe_uid, dstAlphaMode, components);
+ }
+
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
- return result;
+ return success;
}
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen)
{
ID3D11PixelShader* shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen);
if (shader == NULL)
- {
- PanicAlert("Failed to create pixel shader at %s %d\n", __FILE__, __LINE__);
return false;
- }
+
// TODO: Somehow make the debug name a bit more specific
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of PixelShaderCache");
// Make an entry in the table
PSCacheEntry newentry;
newentry.shader = shader;
- newentry.frameCount = frameCount;
PixelShaders[uid] = newentry;
last_entry = &PixelShaders[uid];
@@ -539,20 +552,22 @@ static const unsigned int ps_constant_offset_table[] = {
16, 20, 24, 28, // C_KCOLORS, 16
32, // C_ALPHA, 4
36, 40, 44, 48, 52, 56, 60, 64, // C_TEXDIMS, 32
- 68, 72, // C_ZBIAS, 8
- 76, 80, // C_INDTEXSCALE, 8
- 84, 88, 92, 96, 100, 104, // C_INDTEXMTX, 24
- 108, 112, 116, // C_FOG, 12
- 120, 124, 128, 132, 136, // C_PLIGHTS0, 20
- 140, 144, 148, 152, 156, // C_PLIGHTS1, 20
- 160, 164, 168, 172, 176, // C_PLIGHTS2, 20
- 180, 184, 188, 192, 196, // C_PLIGHTS3, 20
- 200, 204, 208, 212, 216, // C_PLIGHTS4, 20
- 220, 224, 228, 232, 236, // C_PLIGHTS5, 20
- 240, 244, 248, 252, 256, // C_PLIGHTS6, 20
- 260, 264, 268, 272, 276, // C_PLIGHTS7, 20
- 280, 284, 288, 292 // C_PMATERIALS, 16
+ 68, 72, 76, 80, // C_VTEXSCALE, 16 (unused)
+ 84, 88, // C_ZBIAS, 8
+ 92, 96, // C_INDTEXSCALE, 8
+ 100, 104, 108, 112, 116, 120, // C_INDTEXMTX, 24
+ 124, 128, 132, // C_FOG, 12
+ 136, 140, 144, 148, 152, // C_PLIGHTS0, 20
+ 156, 160, 164, 168, 172, // C_PLIGHTS1, 20
+ 176, 180, 184, 188, 192, // C_PLIGHTS2, 20
+ 196, 200, 204, 208, 212, // C_PLIGHTS3, 20
+ 216, 220, 224, 228, 232, // C_PLIGHTS4, 20
+ 236, 240, 244, 248, 252, // C_PLIGHTS5, 20
+ 256, 260, 264, 268, 272, // C_PLIGHTS6, 20
+ 276, 280, 284, 288, 292, // C_PLIGHTS7, 20
+ 296, 300, 304, 308, // C_PMATERIALS, 16
};
+
void Renderer::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
{
psconstants[ps_constant_offset_table[const_number] ] = f1;
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h
index 046f551657..874a47e4c1 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h
+++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.h
@@ -17,11 +17,12 @@
#pragma once
-#include <map>
+#include "PixelShaderGen.h"
#include <d3d11.h>
-class PIXELSHADERUID;
+#include <map>
+
enum DSTALPHA_MODE;
namespace DX11
@@ -52,9 +53,11 @@ private:
struct PSCacheEntry
{
ID3D11PixelShader* shader;
- int frameCount;
- PSCacheEntry() : shader(NULL), frameCount(0) {}
+ PIXELSHADERUIDSAFE safe_uid;
+ std::string code;
+
+ PSCacheEntry() : shader(NULL) {}
void Destroy() { SAFE_RELEASE(shader); }
};
@@ -62,6 +65,7 @@ private:
static PSCache PixelShaders;
static const PSCacheEntry* last_entry;
+ static PIXELSHADERUID last_uid;
};
} // namespace DX11
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp
index fcf3315802..ad23786610 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/PointGeometryShader.cpp
@@ -181,14 +181,15 @@ bool PointGeometryShader::SetShader(u32 components, float pointSize,
p = GenerateVSOutputStruct(p, components, API_D3D11);
p += sprintf(p, "\n%s", POINT_GS_COMMON);
- std::stringstream numTexCoordsStr;
- numTexCoordsStr << xfregs.numTexGen.numTexGens;
+ std::stringstream numTexCoordsStream;
+ numTexCoordsStream << xfregs.numTexGen.numTexGens;
INFO_LOG(VIDEO, "Compiling point geometry shader for components 0x%.08X (num texcoords %d)",
components, xfregs.numTexGen.numTexGens);
+ const std::string& numTexCoordsStr = numTexCoordsStream.str();
D3D_SHADER_MACRO macros[] = {
- { "NUM_TEXCOORDS", numTexCoordsStr.str().c_str() },
+ { "NUM_TEXCOORDS", numTexCoordsStr.c_str() },
{ NULL, NULL }
};
ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code, unsigned int(strlen(code)), macros);
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp
index d0756bfa98..69f0d0215a 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp
@@ -42,6 +42,8 @@
#include "Movie.h"
#include "Television.h"
#include "Host.h"
+#include "BPFunctions.h"
+#include "AVIDump.h"
namespace DX11
{
@@ -61,6 +63,8 @@ ID3D11BlendState* resetblendstate = NULL;
ID3D11DepthStencilState* resetdepthstate = NULL;
ID3D11RasterizerState* resetraststate = NULL;
+static ID3D11Texture2D* s_screenshot_texture = NULL;
+
// GX pipeline state
struct
{
@@ -295,9 +299,14 @@ void SetupDeviceObjects()
hr = D3D::device->CreateRasterizerState(&rastdesc, &resetraststate);
CHECK(hr==S_OK, "Create rasterizer state for Renderer::ResetAPIState");
D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState");
+
+ D3D11_TEXTURE2D_DESC scrtex_desc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight(), 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE);
+ hr = D3D::device->CreateTexture2D(&scrtex_desc, NULL, &s_screenshot_texture);
+ CHECK(hr==S_OK, "Create screenshot staging texture");
+ D3D::SetDebugObjectName((ID3D11DeviceChild*)s_screenshot_texture, "staging screenshot texture");
}
-// Kill off all POOL_DEFAULT device objects.
+// Kill off all device objects
void TeardownDeviceObjects()
{
delete g_framebuffer_manager;
@@ -313,6 +322,7 @@ void TeardownDeviceObjects()
SAFE_RELEASE(resetblendstate);
SAFE_RELEASE(resetdepthstate);
SAFE_RELEASE(resetraststate);
+ SAFE_RELEASE(s_screenshot_texture);
s_television.Shutdown();
}
@@ -343,6 +353,7 @@ Renderer::Renderer()
SetupDeviceObjects();
+
// Setup GX pipeline state
memset(&gx_state.blenddc, 0, sizeof(gx_state.blenddc));
gx_state.blenddc.AlphaToCoverageEnable = FALSE;
@@ -444,51 +455,9 @@ bool Renderer::CheckForResize()
return false;
}
-bool Renderer::SetScissorRect()
+void Renderer::SetScissorRect(const TargetRectangle& rc)
{
- TargetRectangle rc;
- GetScissorRect(rc);
-
- if (rc.left < 0) rc.left = 0;
- if (rc.right < 0) rc.right = 0;
- if (rc.top < 0) rc.top = 0;
- if (rc.bottom < 0) rc.bottom = 0;
-
- if (rc.left > EFB_WIDTH) rc.left = EFB_WIDTH;
- if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
- if (rc.top > EFB_HEIGHT) rc.top = EFB_HEIGHT;
- if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
-
- rc.left = EFBToScaledX(rc.left);
- rc.right = EFBToScaledX(rc.right);
- rc.top = EFBToScaledY(rc.top);
- rc.bottom = EFBToScaledY(rc.bottom);
-
- if (rc.left > rc.right)
- {
- int temp = rc.right;
- rc.right = rc.left;
- rc.left = temp;
- }
- if (rc.top > rc.bottom)
- {
- int temp = rc.bottom;
- rc.bottom = rc.top;
- rc.top = temp;
- }
-
- if (rc.right >= rc.left && rc.bottom >= rc.top)
- {
- D3D::context->RSSetScissorRects(1, rc.AsRECT());
- return true;
- }
- else
- {
- //WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
- *rc.AsRECT() = CD3D11_RECT(0.f, 0.f, s_target_width, s_target_height);
- D3D::context->RSSetScissorRects(1, rc.AsRECT());
- return false;
- }
+ D3D::context->RSSetScissorRects(1, rc.AsRECT());
}
void Renderer::SetColorMask()
@@ -726,15 +695,18 @@ void Renderer::UpdateViewport(Matrix44& vpCorrection)
int Ht = intendedHt;
if (Y + Ht > GetTargetHeight())
Ht = GetTargetHeight() - Y;
-
+
// If GX viewport is off the render target, we must clamp our viewport
// within the bounds. Use the correction matrix to compensate.
ViewportCorrectionMatrix(vpCorrection,
- intendedX, intendedY, intendedWd, intendedHt,
- X, Y, Wd, Ht);
+ (float)intendedX, (float)intendedY,
+ (float)intendedWd, (float)intendedHt,
+ (float)X, (float)Y,
+ (float)Wd, (float)Ht);
// Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work
- D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y, Wd, Ht,
+ D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)X, (float)Y,
+ (float)Wd, (float)Ht,
0.f, // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f;
1.f); // xfregs.viewport.farZ / 16777216.0f;
D3D::context->RSSetViewports(1, &vp);
@@ -779,7 +751,7 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
else if (convtype == 2) pixel_shader = PixelShaderCache::ReinterpRGBA6ToRGB8(true);
else
{
- PanicAlert("Trying to reinterpret pixel data with unsupported conversion type %d", convtype);
+ ERROR_LOG(VIDEO, "Trying to reinterpret pixel data with unsupported conversion type %d", convtype);
return;
}
@@ -876,15 +848,11 @@ void Renderer::SetBlendMode(bool forceUpdate)
bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &rc)
{
// copy back buffer to system memory
- ID3D11Texture2D* buftex;
- D3D11_TEXTURE2D_DESC tex_desc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight(), 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE);
- HRESULT hr = D3D::device->CreateTexture2D(&tex_desc, NULL, &buftex);
- if (FAILED(hr)) PanicAlert("Failed to create screenshot buffer texture");
- D3D::context->CopyResource(buftex, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex());
+ D3D::context->CopyResource(s_screenshot_texture, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex());
// D3DX11SaveTextureToFileA doesn't allow us to ignore the alpha channel, so we need to strip it out ourselves
D3D11_MAPPED_SUBRESOURCE map;
- D3D::context->Map(buftex, 0, D3D11_MAP_READ_WRITE, 0, &map);
+ D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ_WRITE, 0, &map);
for (unsigned int y = 0; y < D3D::GetBackBufferHeight(); ++y)
{
u8* ptr = (u8*)map.pData + y * map.RowPitch + 3;
@@ -894,21 +862,38 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle
ptr += 4;
}
}
- D3D::context->Unmap(buftex, 0);
+ D3D::context->Unmap(s_screenshot_texture, 0);
// ready to be saved
- hr = PD3DX11SaveTextureToFileA(D3D::context, buftex, D3DX11_IFF_PNG, filename.c_str());
- buftex->Release();
+ HRESULT hr = PD3DX11SaveTextureToFileA(D3D::context, s_screenshot_texture, D3DX11_IFF_PNG, filename.c_str());
return SUCCEEDED(hr);
}
+void formatBufferDump(const char *in, char *out, int w, int h, int p)
+{
+ for (int y = 0; y < h; ++y)
+ {
+ const u8 *line = (u8*)(in + (h - y - 1) * p);
+ for (int x = 0; x < w; ++x)
+ {
+ out[0] = line[2];
+ out[1] = line[1];
+ out[2] = line[0];
+ out += 3;
+ line += 4;
+ }
+ }
+}
// This function has the final picture. We adjust the aspect ratio here.
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
{
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
{
+ if (g_ActiveConfig.bDumpFrames && frame_data)
+ AVIDump::AddFrame(frame_data);
+
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -920,6 +905,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
{
+ if (g_ActiveConfig.bDumpFrames && frame_data)
+ AVIDump::AddFrame(frame_data);
+
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -1025,6 +1013,64 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
s_bScreenshot = false;
}
+ // Dump frames
+ static int w = 0, h = 0;
+ if (g_ActiveConfig.bDumpFrames)
+ {
+ static int s_recordWidth;
+ static int s_recordHeight;
+
+ D3D::context->CopyResource(s_screenshot_texture, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex());
+ if (!bLastFrameDumped)
+ {
+ s_recordWidth = dst_rect.GetWidth();
+ s_recordHeight = dst_rect.GetHeight();
+ bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
+ if (!bAVIDumping)
+ {
+ PanicAlert("Error dumping frames to AVI.");
+ }
+ else
+ {
+ char msg [255];
+ sprintf_s(msg,255, "Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)",
+ File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), s_recordWidth, s_recordHeight);
+ OSD::AddMessage(msg, 2000);
+ }
+ }
+ if (bAVIDumping)
+ {
+ D3D11_MAPPED_SUBRESOURCE map;
+ D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map);
+
+ if (!frame_data || w != s_recordWidth || h != s_recordHeight)
+ {
+ delete[] frame_data;
+ frame_data = new char[3 * s_recordWidth * s_recordHeight];
+ w = s_recordWidth;
+ h = s_recordHeight;
+ }
+ char* source_ptr = (char*)map.pData + dst_rect.left*4 + dst_rect.top*map.RowPitch;
+ formatBufferDump(source_ptr, frame_data, s_recordWidth, s_recordHeight, map.RowPitch);
+ AVIDump::AddFrame(frame_data);
+ D3D::context->Unmap(s_screenshot_texture, 0);
+ }
+ bLastFrameDumped = true;
+ }
+ else
+ {
+ if (bLastFrameDumped && bAVIDumping)
+ {
+ SAFE_DELETE_ARRAY(frame_data);
+ w = h = 0;
+
+ AVIDump::Stop();
+ bAVIDumping = false;
+ OSD::AddMessage("Stop dumping frames to AVI", 2000);
+ }
+ bLastFrameDumped = false;
+ }
+
// Finish up the current frame, print some stats
if (g_ActiveConfig.bShowFPS)
{
@@ -1063,12 +1109,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
DLCache::ProgressiveCleanup();
TextureCache::Cleanup();
- // reload textures if these settings changed
- if (g_Config.bSafeTextureCache != g_ActiveConfig.bSafeTextureCache ||
- g_Config.bUseNativeMips != g_ActiveConfig.bUseNativeMips)
+ // Reload textures if this settings changes
+ if (g_Config.bUseNativeMips != g_ActiveConfig.bUseNativeMips)
TextureCache::Invalidate(false);
- // Enable any configuration changes
+ // Enable configuration changes
UpdateActiveConfig();
SetWindowSize(fbWidth, fbHeight);
@@ -1163,7 +1208,7 @@ void Renderer::RestoreAPIState()
D3D::stateman->PopDepthState();
D3D::stateman->PopRasterizerState();
VertexShaderManager::SetViewportChanged();
- SetScissorRect();
+ BPFunctions::SetScissor();
}
void Renderer::ApplyState(bool bUseDstAlpha)
@@ -1385,4 +1430,4 @@ void Renderer::SetInterlacingMode()
// TODO
}
-} // namespace DX11 \ No newline at end of file
+} // namespace DX11
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.h b/Source/Plugins/Plugin_VideoDX11/Src/Render.h
index 5d1c24bc23..8f6c78fae1 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/Render.h
+++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.h
@@ -15,7 +15,7 @@ public:
void SetColorMask();
void SetBlendMode(bool forceUpdate);
- bool SetScissorRect();
+ void SetScissorRect(const TargetRectangle& rc);
void SetGenerationMode();
void SetDepthMode();
void SetLogicOpMode();
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp
index 39018c83bc..e59fbd496e 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp
@@ -102,12 +102,12 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
bool isIntensity, bool scaleByHalf, unsigned int cbufid,
const float *colmat)
{
- if (!isDynamic || g_ActiveConfig.bCopyEFBToTexture)
+ if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture)
{
g_renderer->ResetAPIState();
// stretch picture with increased internal resolution
- const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH);
+ const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtual_width, (float)virtual_height);
D3D::context->RSSetViewports(1, &vp);
// set transformation
@@ -149,17 +149,15 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
if (!g_ActiveConfig.bCopyEFBToTexture)
{
u8* dst = Memory::GetPointer(dstAddr);
- size_t encodeSize = g_encoder->Encode(dst, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf);
- hash = GetHash64(dst, encodeSize, g_ActiveConfig.iSafeTextureCache_ColorSamples);
- if (g_ActiveConfig.bEFBCopyCacheEnable)
- {
- // If the texture in RAM is already in the texture cache,
- // do not copy it again as it has not changed.
- if (TextureCache::Find(dstAddr, hash))
- return;
- }
+ size_t encoded_size = g_encoder->Encode(dst, dstFormat, srcFormat, srcRect, isIntensity, scaleByHalf);
+
+ hash = GetHash64(dst, (int)encoded_size, g_ActiveConfig.iSafeTextureCache_ColorSamples);
- TextureCache::MakeRangeDynamic(dstAddr, encodeSize);
+ // Mark texture entries in destination address range dynamic unless caching is enabled and the texture entry is up to date
+ if (!g_ActiveConfig.bEFBCopyCacheEnable)
+ TextureCache::MakeRangeDynamic(addr, (u32)encoded_size);
+ else if (!TextureCache::Find(addr, hash))
+ TextureCache::MakeRangeDynamic(addr, (u32)encoded_size);
}
}
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp
index e1e40047e4..1079863347 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp
@@ -228,12 +228,13 @@ void VertexManager::vFlush()
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
tex.texTlut[i&3].tlut_format,
(tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips,
- (tex.texMode1[i&3].max_lod >> 4));
+ tex.texMode1[i&3].max_lod >> 4,
+ tex.texImage1[i&3].image_type);
if (tentry)
{
// 0s are probably for no manual wrapping needed.
- PixelShaderManager::SetTexDims(i, tentry->realW, tentry->realH, 0, 0);
+ PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, tentry->virtual_width, tentry->virtual_height, 0, 0, API_D3D11);
}
else
ERROR_LOG(VIDEO, "error loading texture");
@@ -242,7 +243,7 @@ void VertexManager::vFlush()
// set global constants
VertexShaderManager::SetConstants();
- PixelShaderManager::SetConstants();
+ PixelShaderManager::SetConstants(API_D3D11);
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp
index 041caba28c..d727ce1ebf 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.cpp
@@ -37,6 +37,7 @@ namespace DX11 {
VertexShaderCache::VSCache VertexShaderCache::vshaders;
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
+VERTEXSHADERUID VertexShaderCache::last_uid;
static ID3D11VertexShader* SimpleVertexShader = NULL;
static ID3D11VertexShader* ClearVertexShader = NULL;
@@ -174,6 +175,11 @@ void VertexShaderCache::Init()
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
VertexShaderCacheInserter inserter;
g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
+
+ if (g_Config.bEnableShaderDebugging)
+ Clear();
+
+ last_entry = NULL;
}
void VertexShaderCache::Clear()
@@ -181,6 +187,8 @@ void VertexShaderCache::Clear()
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
iter->second.Destroy();
vshaders.clear();
+
+ last_entry = NULL;
}
void VertexShaderCache::Shutdown()
@@ -202,22 +210,26 @@ bool VertexShaderCache::SetShader(u32 components)
{
VERTEXSHADERUID uid;
GetVertexShaderId(&uid, components);
- if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
+ if (last_entry)
{
- GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
- return (vshaders[uid].shader != NULL);
+ if (uid == last_uid)
+ {
+ GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
+ ValidateVertexShaderIDs(API_D3D11, last_entry->safe_uid, last_entry->code, components);
+ return (last_entry->shader != NULL);
+ }
}
- memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
+ last_uid = uid;
VSCache::iterator iter = vshaders.find(uid);
if (iter != vshaders.end())
{
- iter->second.frameCount = frameCount;
const VSCacheEntry &entry = iter->second;
last_entry = &entry;
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
+ ValidateVertexShaderIDs(API_D3D11, entry.safe_uid, entry.code, components);
return (entry.shader != NULL);
}
@@ -228,34 +240,36 @@ bool VertexShaderCache::SetShader(u32 components)
if (pbytecode == NULL)
{
- PanicAlert("Failed to compile Vertex Shader %s %d:\n\n%s", __FILE__, __LINE__, code);
GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true);
return false;
}
g_vs_disk_cache.Append(uid, pbytecode->Data(), pbytecode->Size());
- g_vs_disk_cache.Sync();
- bool result = InsertByteCode(uid, pbytecode);
+ bool success = InsertByteCode(uid, pbytecode);
pbytecode->Release();
+
+ if (g_ActiveConfig.bEnableShaderDebugging && success)
+ {
+ vshaders[uid].code = code;
+ GetSafeVertexShaderId(&vshaders[uid].safe_uid, components);
+ }
+
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
- return result;
+ return success;
}
bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, D3DBlob* bcodeblob)
{
ID3D11VertexShader* shader = D3D::CreateVertexShaderFromByteCode(bcodeblob);
if (shader == NULL)
- {
- PanicAlert("Failed to create vertex shader from %p size %d at %s %d\n", bcodeblob->Data(), bcodeblob->Size(), __FILE__, __LINE__);
return false;
- }
+
// TODO: Somehow make the debug name a bit more specific
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a vertex shader of VertexShaderCache");
// Make an entry in the table
VSCacheEntry entry;
entry.shader = shader;
- entry.frameCount = frameCount;
entry.SetByteCode(bcodeblob);
vshaders[uid] = entry;
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h
index 3c7dadd3e7..6d9537606a 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h
+++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexShaderCache.h
@@ -18,12 +18,12 @@
#ifndef _VERTEXSHADERCACHE_H
#define _VERTEXSHADERCACHE_H
-#include <map>
+#include "VertexShaderGen.h"
#include "D3DBase.h"
#include "D3DBlob.h"
-class VERTEXSHADERUID;
+#include <map>
namespace DX11 {
@@ -51,9 +51,11 @@ private:
{
ID3D11VertexShader* shader;
D3DBlob* bytecode; // needed to initialize the input layout
- int frameCount;
- VSCacheEntry() : shader(NULL), bytecode(NULL), frameCount(0) {}
+ VERTEXSHADERUIDSAFE safe_uid;
+ std::string code;
+
+ VSCacheEntry() : shader(NULL), bytecode(NULL) {}
void SetByteCode(D3DBlob* blob)
{
SAFE_RELEASE(bytecode);
@@ -70,6 +72,7 @@ private:
static VSCache vshaders;
static const VSCacheEntry* last_entry;
+ static VERTEXSHADERUID last_uid;
};
} // namespace DX11
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp
index ba93890e2b..ba3a67108b 100644
--- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp
+++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp
@@ -68,9 +68,9 @@ unsigned int VideoBackend::PeekMessages()
void VideoBackend::UpdateFPSDisplay(const char *text)
{
- char temp[512];
- sprintf_s(temp, sizeof temp, "%s | DX11 | %s", scm_rev_str, text);
- SetWindowTextA(EmuWindow::GetWnd(), temp);
+ TCHAR temp[512];
+ swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX11 | %hs"), scm_rev_str, text);
+ EmuWindow::SetWindowText(temp);
}
std::string VideoBackend::GetName()
@@ -150,6 +150,7 @@ void VideoBackend::ShowConfig(void *_hParent)
bool VideoBackend::Initialize(void *&window_handle)
{
+ InitializeShared();
InitBackendInfo();
frameCount = 0;
diff --git a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj
index 838004a605..604fea8a2b 100644
--- a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj
+++ b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcxproj
@@ -46,7 +46,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -57,7 +57,6 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp
index de610eab39..ff3f68a6cd 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp
@@ -28,7 +28,8 @@ D3DXCOMPILESHADERTYPE PD3DXCompileShader = NULL;
namespace DX9
{
-
+static char vsVersions[5][7] = {"ERROR", "vs_1_4", "vs_2_a", "vs_3_0", "vs_4_0"};
+static char psVersions[5][7] = {"ERROR", "ps_1_4", "ps_2_a", "ps_3_0", "ps_4_0"};
// D3DX
HINSTANCE hD3DXDll = NULL;
int d3dx_dll_ref = 0;
@@ -55,6 +56,7 @@ static bool auto_depth_stencil = false;
#define VENDOR_NVIDIA 4318
#define VENDOR_ATI 4098
+#define VENDOR_INTEL 32902
bool bFrameInProgress = false;
@@ -112,6 +114,10 @@ bool IsATIDevice()
{
return GetCurAdapter().ident.VendorId == VENDOR_ATI;
}
+bool IsIntelDevice()
+{
+ return GetCurAdapter().ident.VendorId == VENDOR_INTEL;
+}
HRESULT Init()
@@ -139,6 +145,11 @@ HRESULT Init()
int adapter = g_Config.iAdapter;
D3D->GetDeviceCaps((adapter >= 0 && adapter < std::min(MAX_ADAPTERS, numAdapters)) ? adapter : D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
Enumerate();
+ if(IsIntelDevice()){
+ // Murder the a because Intel doesn't support 2.0a because the 'a' part was a ATI and Nvidia war going on
+ psVersions[2][5] = '0';
+ vsVersions[2][5] = '0';
+ }
return S_OK;
}
@@ -522,16 +533,14 @@ D3DFORMAT GetSupportedDepthSurfaceFormat(D3DFORMAT target_format)
const char *VertexShaderVersionString()
{
- static const char *versions[5] = {"ERROR", "vs_1_4", "vs_2_a", "vs_3_0", "vs_4_0"};
int version = ((D3D::caps.VertexShaderVersion >> 8) & 0xFF);
- return versions[std::min(4, version)];
+ return vsVersions[std::min(4, version)];
}
const char *PixelShaderVersionString()
{
- static const char *versions[5] = {"ERROR", "ps_1_4", "ps_2_a", "ps_3_0", "ps_4_0"};
int version = ((D3D::caps.PixelShaderVersion >> 8) & 0xFF);
- return versions[std::min(4, version)];
+ return psVersions[std::min(4, version)];
}
LPDIRECT3DSURFACE9 GetBackBufferSurface()
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h
index f4a5244dbe..d1e7eeaa91 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h
@@ -47,6 +47,7 @@ namespace D3D
#define FOURCC_NULL ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')))
bool IsATIDevice();
+bool IsIntelDevice();
HRESULT Init();
HRESULT Create(int adapter, HWND wnd, int resolution, int aa_mode, bool auto_depth);
void Close();
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp
index cfb74df225..9510ad444c 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp
@@ -383,7 +383,7 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture,
float v2=((float)rSource->bottom) * sh;
float g = 1.0f/Gamma;
- struct Q2DVertex { float x,y,z,rhw,u,v,w,h,G; } coords[4] = {
+ const struct Q2DVertex { float x,y,z,rhw,u,v,w,h,G; } coords[4] = {
{-1.0f - dw,-1.0f + dh, 0.0f,1.0f, u1, v2, sw, sh, g},
{-1.0f - dw, 1.0f + dh, 0.0f,1.0f, u1, v1, sw, sh, g},
{ 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, sw, sh, g},
@@ -434,15 +434,13 @@ void drawShadedTexSubQuad(IDirect3DTexture9 *texture,
// Fills a certain area of the current render target with the specified color
// Z buffer disabled; destination coordinates normalized to (-1;1)
-void drawColorQuad(int DestWidth, int DestHeight, u32 Color, float x1, float y1, float x2, float y2)
+void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
{
- float dw = 1.f / (float)DestWidth;
- float dh = 1.f / (float)DestHeight;
struct CQVertex { float x, y, z, rhw; u32 col; } coords[4] = {
- { x1-dw, y2+dh, 0.f, 1.f, Color },
- { x2-dw, y2+dh, 0.f, 1.f, Color },
- { x1-dw, y1+dh, 0.f, 1.f, Color },
- { x2-dw, y1+dh, 0.f, 1.f, Color },
+ { x1, y2, 0.f, 1.f, Color },
+ { x2, y2, 0.f, 1.f, Color },
+ { x1, y1, 0.f, 1.f, Color },
+ { x2, y1, 0.f, 1.f, Color },
};
dev->SetVertexShader(VertexShaderCache::GetClearVertexShader());
dev->SetPixelShader(PixelShaderCache::GetClearProgram());
@@ -451,15 +449,13 @@ void drawColorQuad(int DestWidth, int DestHeight, u32 Color, float x1, float y1,
RestoreShaders();
}
-void drawClearQuad(int DestWidth, int DestHeight, u32 Color, float z, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader)
+void drawClearQuad(u32 Color,float z,IDirect3DPixelShader9 *PShader,IDirect3DVertexShader9 *Vshader)
{
- float dw = 1.f / (float)DestWidth;
- float dh = 1.f / (float)DestHeight;
struct Q2DVertex { float x,y,z,rhw;u32 color;} coords[4] = {
- {-1.0f-dw, 1.0f+dh, z, 1.0f, Color},
- { 1.0f-dw, 1.0f+dh, z, 1.0f, Color},
- { 1.0f-dw, -1.0f+dh, z, 1.0f, Color},
- {-1.0f-dw, -1.0f+dh, z, 1.0f, Color}
+ {-1.0f, 1.0f, z, 1.0f, Color},
+ { 1.0f, 1.0f, z, 1.0f, Color},
+ { 1.0f, -1.0f, z, 1.0f, Color},
+ {-1.0f, -1.0f, z, 1.0f, Color}
};
dev->SetVertexShader(Vshader);
dev->SetPixelShader(PShader);
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h
index 93e60f938b..882f112ece 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h
@@ -82,8 +82,8 @@ namespace D3D
IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader,
float Gamma = 1.0f);
- void drawClearQuad(int DestWidth, int DestHeight, u32 Color, float z, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader);
- void drawColorQuad(int DestWidth, int DestHeight, u32 Color, float x1, float y1, float x2, float y2);
+ void drawClearQuad(u32 Color, float z, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader);
+ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2);
void SaveRenderStates();
void RestoreRenderStates();
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp
index f76837837d..f66d096ab6 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp
@@ -43,6 +43,7 @@ namespace DX9
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry;
+PIXELSHADERUID PixelShaderCache::last_uid;
static LinearDiskCache<PIXELSHADERUID, u8> g_ps_disk_cache;
static std::set<u32> unique_shaders;
@@ -233,6 +234,8 @@ static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConv
void PixelShaderCache::Init()
{
+ last_entry = NULL;
+
//program used for clear screen
{
char pprog[3072];
@@ -283,6 +286,9 @@ void PixelShaderCache::Init()
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
PixelShaderCacheInserter inserter;
g_ps_disk_cache.OpenAndRead(cache_filename, inserter);
+
+ if (g_Config.bEnableShaderDebugging)
+ Clear();
}
// ONLY to be used during shutdown.
@@ -292,7 +298,7 @@ void PixelShaderCache::Clear()
iter->second.Destroy();
PixelShaders.clear();
- memset(&last_pixel_shader_uid, 0xFF, sizeof(last_pixel_shader_uid));
+ last_entry = NULL;
}
void PixelShaderCache::Shutdown()
@@ -326,41 +332,47 @@ void PixelShaderCache::Shutdown()
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
{
+ const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30;
PIXELSHADERUID uid;
- GetPixelShaderId(&uid, dstAlphaMode);
+ GetPixelShaderId(&uid, dstAlphaMode, components);
// Check if the shader is already set
- if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
+ if (last_entry)
{
- PSCache::const_iterator iter = PixelShaders.find(uid);
- GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
- return (iter != PixelShaders.end() && iter->second.shader);
+ if (uid == last_uid)
+ {
+ GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
+ ValidatePixelShaderIDs(api, last_entry->safe_uid, last_entry->code, dstAlphaMode, components);
+ return last_entry->shader != NULL;
+ }
}
- memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
+ last_uid = uid;
// Check if the shader is already in the cache
PSCache::iterator iter;
iter = PixelShaders.find(uid);
if (iter != PixelShaders.end())
{
- iter->second.frameCount = frameCount;
const PSCacheEntry &entry = iter->second;
last_entry = &entry;
if (entry.shader) D3D::SetPixelShader(entry.shader);
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
+ ValidatePixelShaderIDs(api, entry.safe_uid, entry.code, dstAlphaMode, components);
return (entry.shader != NULL);
}
-
// Need to compile a new shader
- const char *code = GeneratePixelShaderCode(dstAlphaMode, ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30, components);
+ const char *code = GeneratePixelShaderCode(dstAlphaMode, api, components);
- u32 code_hash = HashAdler32((const u8 *)code, strlen(code));
- unique_shaders.insert(code_hash);
- SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
+ if (g_ActiveConfig.bEnableShaderDebugging)
+ {
+ u32 code_hash = HashAdler32((const u8 *)code, strlen(code));
+ unique_shaders.insert(code_hash);
+ SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
+ }
#if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
@@ -381,14 +393,19 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
// Insert the bytecode into the caches
g_ps_disk_cache.Append(uid, bytecode, bytecodelen);
- g_ps_disk_cache.Sync();
// And insert it into the shader cache.
- bool result = InsertByteCode(uid, bytecode, bytecodelen, true);
+ bool success = InsertByteCode(uid, bytecode, bytecodelen, true);
delete [] bytecode;
+ if (g_ActiveConfig.bEnableShaderDebugging && success)
+ {
+ PixelShaders[uid].code = code;
+ GetSafePixelShaderId(&PixelShaders[uid].safe_uid, dstAlphaMode, components);
+ }
+
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
- return result;
+ return success;
}
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate)
@@ -398,7 +415,6 @@ bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytec
// Make an entry in the table
PSCacheEntry newentry;
newentry.shader = shader;
- newentry.frameCount = frameCount;
PixelShaders[uid] = newentry;
last_entry = &PixelShaders[uid];
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h
index 2f3c552e2a..c771984d36 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h
@@ -40,9 +40,11 @@ private:
{
LPDIRECT3DPIXELSHADER9 shader;
bool owns_shader;
- int frameCount;
- PSCacheEntry() : shader(NULL), owns_shader(true), frameCount(0) {}
+ PIXELSHADERUIDSAFE safe_uid;
+ std::string code;
+
+ PSCacheEntry() : shader(NULL), owns_shader(true) {}
void Destroy()
{
if (shader && owns_shader)
@@ -55,6 +57,7 @@ private:
static PSCache PixelShaders;
static const PSCacheEntry *last_entry;
+ static PIXELSHADERUID last_uid;
static void Clear();
public:
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
index e333cbc168..a5aaa6485b 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
@@ -53,18 +53,13 @@
#include "Debugger.h"
#include "Core.h"
#include "Movie.h"
+#include "BPFunctions.h"
namespace DX9
{
static int s_fps = 0;
-static int s_recordWidth;
-static int s_recordHeight;
-
-static bool s_bLastFrameDumped;
-static bool s_bAVIDumping;
-
static u32 s_blendMode;
static u32 s_LastAA;
static bool IS_AMD;
@@ -296,9 +291,6 @@ Renderer::Renderer()
// Make sure to use valid texture sizes
D3D::FixTextureSize(s_target_width, s_target_height);
- s_bLastFrameDumped = false;
- s_bAVIDumping = false;
-
// We're not using fixed function.
// Let's just set the matrices to identity to be sure.
D3DXMATRIX mtx;
@@ -341,10 +333,6 @@ Renderer::~Renderer()
D3D::Present();
D3D::Close();
- if (s_bAVIDumping)
- {
- AVIDump::Stop();
- }
delete[] st;
}
@@ -426,55 +414,9 @@ bool Renderer::CheckForResize()
return false;
}
-bool Renderer::SetScissorRect()
+void Renderer::SetScissorRect(const TargetRectangle& rc)
{
- TargetRectangle rc;
- GetScissorRect(rc);
-
- if (rc.left < 0) rc.left = 0;
- if (rc.right < 0) rc.right = 0;
- if (rc.top < 0) rc.top = 0;
- if (rc.bottom < 0) rc.bottom = 0;
-
- if (rc.left > EFB_WIDTH) rc.left = EFB_WIDTH;
- if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
- if (rc.top > EFB_HEIGHT) rc.top = EFB_HEIGHT;
- if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
-
- if (rc.left > rc.right)
- {
- int temp = rc.right;
- rc.right = rc.left;
- rc.left = temp;
- }
- if (rc.top > rc.bottom)
- {
- int temp = rc.bottom;
- rc.bottom = rc.top;
- rc.top = temp;
- }
-
- rc.left = EFBToScaledX(rc.left);
- rc.top = EFBToScaledY(rc.top);
- rc.right = EFBToScaledX(rc.right);
- rc.bottom = EFBToScaledY(rc.bottom);
-
- // Check that the coordinates are good
- if (rc.right != rc.left && rc.bottom != rc.top)
- {
- D3D::dev->SetScissorRect(rc.AsRECT());
- return true;
- }
- else
- {
- //WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
- rc.left = 0;
- rc.top = 0;
- rc.right = s_target_width;
- rc.bottom = s_target_height;
- D3D::dev->SetScissorRect(rc.AsRECT());
- }
- return false;
+ D3D::dev->SetScissorRect(rc.AsRECT());
}
void Renderer::SetColorMask()
@@ -680,7 +622,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
{
// TODO: Speed this up by batching pokes?
ResetAPIState();
- D3D::drawColorQuad(GetTargetWidth(), GetTargetHeight(), poke_data,
+ D3D::drawColorQuad(poke_data,
(float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f,
- (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f,
(float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f,
@@ -805,7 +747,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
vp.MinZ = 0.0;
vp.MaxZ = 1.0;
D3D::dev->SetViewport(&vp);
- D3D::drawClearQuad(GetTargetWidth(), GetTargetHeight(), color, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader());
+ D3D::drawClearQuad(color, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader());
RestoreAPIState();
}
@@ -819,7 +761,7 @@ void Renderer::ReinterpretPixelData(unsigned int convtype)
else if (convtype == 2) pixel_shader = PixelShaderCache::ReinterpRGBA6ToRGB8();
else
{
- PanicAlert("Trying to reinterpret pixel data with unsupported conversion type %d", convtype);
+ ERROR_LOG(VIDEO, "Trying to reinterpret pixel data with unsupported conversion type %d", convtype);
return;
}
@@ -889,12 +831,11 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle
// This function has the final picture. We adjust the aspect ratio here.
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
{
- static char* data = 0;
- static int w = 0, h = 0;
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
{
- if (g_ActiveConfig.bDumpFrames && data)
- AVIDump::AddFrame(data);
+ if (g_ActiveConfig.bDumpFrames && frame_data)
+ AVIDump::AddFrame(frame_data);
+
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -907,6 +848,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
{
+ if (g_ActiveConfig.bDumpFrames && frame_data)
+ AVIDump::AddFrame(frame_data);
+
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -952,7 +896,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
D3D::dev->SetViewport(&vp);
- D3D::drawClearQuad(GetTargetWidth(), GetTargetHeight(), 0, 1.0, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader());
+ D3D::drawClearQuad(0, 1.0, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader());
}
else
{
@@ -1072,15 +1016,21 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
SaveScreenshot(s_sScreenshotName, dst_rect);
s_bScreenshot = false;
}
+
+ // Dump frames
+ static int w = 0, h = 0;
if (g_ActiveConfig.bDumpFrames)
{
+ static int s_recordWidth;
+ static int s_recordHeight;
+
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
- if (!s_bLastFrameDumped)
+ if (!bLastFrameDumped)
{
s_recordWidth = dst_rect.GetWidth();
s_recordHeight = dst_rect.GetHeight();
- s_bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
- if (!s_bAVIDumping)
+ bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
+ if (!bAVIDumping)
{
PanicAlert("Error dumping frames to AVI.");
}
@@ -1092,40 +1042,40 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
OSD::AddMessage(msg, 2000);
}
}
- if (s_bAVIDumping)
+ if (bAVIDumping)
{
D3DLOCKED_RECT rect;
if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, dst_rect.AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
{
- if (!data || w != s_recordWidth || h != s_recordHeight)
+ if (!frame_data || w != s_recordWidth || h != s_recordHeight)
{
- free(data);
- data = (char*)malloc(3 * s_recordWidth * s_recordHeight);
+ delete[] frame_data;
+ frame_data = new char[3 * s_recordWidth * s_recordHeight];
w = s_recordWidth;
h = s_recordHeight;
}
- formatBufferDump((const char*)rect.pBits, data, s_recordWidth, s_recordHeight, rect.Pitch);
- AVIDump::AddFrame(data);
+ formatBufferDump((const char*)rect.pBits, frame_data, s_recordWidth, s_recordHeight, rect.Pitch);
+ AVIDump::AddFrame(frame_data);
ScreenShootMEMSurface->UnlockRect();
}
}
- s_bLastFrameDumped = true;
+ bLastFrameDumped = true;
}
else
{
- if (s_bLastFrameDumped && s_bAVIDumping)
+ if (bLastFrameDumped && bAVIDumping)
{
- if (data)
+ if (frame_data)
{
- free(data);
- data = 0;
+ delete[] frame_data;
+ frame_data = 0;
w = h = 0;
}
AVIDump::Stop();
- s_bAVIDumping = false;
+ bAVIDumping = false;
OSD::AddMessage("Stop dumping frames to AVI", 2000);
}
- s_bLastFrameDumped = false;
+ bLastFrameDumped = false;
}
// Finish up the current frame, print some stats
@@ -1164,12 +1114,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
DLCache::ProgressiveCleanup();
TextureCache::Cleanup();
- // reload textures if these settings changed
- if (g_Config.bSafeTextureCache != g_ActiveConfig.bSafeTextureCache ||
- g_Config.bUseNativeMips != g_ActiveConfig.bUseNativeMips)
+ // Reload textures if these settings changed
+ if (g_Config.bUseNativeMips != g_ActiveConfig.bUseNativeMips)
TextureCache::Invalidate(false);
- // Enable any configuration changes
+ // Enable configuration changes
UpdateActiveConfig();
SetWindowSize(fbWidth, fbHeight);
@@ -1293,7 +1242,7 @@ void Renderer::RestoreAPIState()
D3D::SetRenderState(D3DRS_FILLMODE, g_ActiveConfig.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
VertexShaderManager::SetViewportChanged();
- SetScissorRect();
+ BPFunctions::SetScissor();
if (bpmem.zmode.testenable) {
D3D::SetRenderState(D3DRS_ZENABLE, TRUE);
if (bpmem.zmode.updateenable)
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.h b/Source/Plugins/Plugin_VideoDX9/Src/Render.h
index b3c89f82f9..6e5198b3cd 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/Render.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.h
@@ -15,7 +15,7 @@ public:
void SetColorMask();
void SetBlendMode(bool forceUpdate);
- bool SetScissorRect();
+ void SetScissorRect(const TargetRectangle& rc);
void SetGenerationMode();
void SetDepthMode();
void SetLogicOpMode();
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp
index 7c741e08a9..2a3f12ddcf 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp
@@ -21,6 +21,7 @@
#include "Statistics.h"
#include "MemoryUtil.h"
#include "Hash.h"
+#include "HW/Memmap.h"
#include "CommonPaths.h"
#include "FileUtil.h"
@@ -78,7 +79,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
FramebufferManager::GetEFBDepthTexture() :
FramebufferManager::GetEFBColorTexture();
- if (!isDynamic || g_ActiveConfig.bCopyEFBToTexture)
+ if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture)
{
LPDIRECT3DSURFACE9 Rendersurf = NULL;
texture->GetSurfaceLevel(0, &Rendersurf);
@@ -90,15 +91,15 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
// Stretch picture with increased internal resolution
vp.X = 0;
vp.Y = 0;
- vp.Width = virtualW;
- vp.Height = virtualH;
+ vp.Width = virtual_width;
+ vp.Height = virtual_height;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
D3D::dev->SetViewport(&vp);
RECT destrect;
- destrect.bottom = virtualH;
+ destrect.bottom = virtual_height;
destrect.left = 0;
- destrect.right = virtualW;
+ destrect.right = virtual_width;
destrect.top = 0;
PixelShaderManager::SetColorMatrix(colmat); // set transformation
@@ -133,7 +134,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
D3D::drawShadedTexQuad(read_texture, &sourcerect,
Renderer::GetTargetWidth(), Renderer::GetTargetHeight(),
- virtualW, virtualH,
+ virtual_width, virtual_height,
// TODO: why is D3DFMT_D24X8 singled out here? why not D3DFMT_D24X4S4/D24S8/D24FS8/D32/D16/D15S1 too, or none of them?
PixelShaderCache::GetDepthMatrixProgram(SSAAMode, (srcFormat == PIXELFMT_Z24) && bformat != FOURCC_RAWZ && bformat != D3DFMT_D24X8),
VertexShaderCache::GetSimpleVertexShader(SSAAMode));
@@ -143,16 +144,25 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
if (!g_ActiveConfig.bCopyEFBToTexture)
{
- hash = TextureConverter::EncodeToRamFromTexture(
- addr,
- read_texture,
- Renderer::GetTargetWidth(),
- Renderer::GetTargetHeight(),
- srcFormat == PIXELFMT_Z24,
- isIntensity,
- dstFormat,
- scaleByHalf,
- srcRect);
+ int encoded_size = TextureConverter::EncodeToRamFromTexture(
+ addr,
+ read_texture,
+ Renderer::GetTargetWidth(),
+ Renderer::GetTargetHeight(),
+ srcFormat == PIXELFMT_Z24,
+ isIntensity,
+ dstFormat,
+ scaleByHalf,
+ srcRect);
+
+ u8* dst = Memory::GetPointer(addr);
+ hash = GetHash64(dst,encoded_size,g_ActiveConfig.iSafeTextureCache_ColorSamples);
+
+ // Mark texture entries in destination address range dynamic unless caching is enabled and the texture entry is up to date
+ if (!g_ActiveConfig.bEFBCopyCacheEnable)
+ TextureCache::MakeRangeDynamic(addr,encoded_size);
+ else if (!TextureCache::Find(addr, hash))
+ TextureCache::MakeRangeDynamic(addr,encoded_size);
}
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp
index d14a3f29ea..7c38b154b9 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp
@@ -252,10 +252,10 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr
s_texConvReadSurface = TrnBuffers[index].ReadSurface;
Rendersurf = TrnBuffers[index].RenderSurface;
-
+
hr = D3D::dev->SetDepthStencilSurface(NULL);
hr = D3D::dev->SetRenderTarget(0, Rendersurf);
-
+
if (linearFilter)
{
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
@@ -290,7 +290,7 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
// .. and then read back the results.
// TODO: make this less slow.
-
+
hr = D3D::dev->GetRenderTargetData(Rendersurf,s_texConvReadSurface);
D3DLOCKED_RECT drect;
@@ -313,76 +313,7 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr
hr = s_texConvReadSurface->UnlockRect();
}
-void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
-{
- u32 format = copyfmt;
-
- if (bFromZBuffer)
- {
- format |= _GX_TF_ZTF;
- if (copyfmt == 11)
- format = GX_TF_Z16;
- else if (format < GX_TF_Z8 || format > GX_TF_Z24X8)
- format |= _GX_TF_CTF;
- }
- else
- if (copyfmt > GX_TF_RGBA8 || (copyfmt < GX_TF_RGB565 && !bIsIntensityFmt))
- format |= _GX_TF_CTF;
-
- LPDIRECT3DPIXELSHADER9 texconv_shader = GetOrCreateEncodingShader(format);
- if (!texconv_shader)
- return;
-
- u8 *dest_ptr = Memory::GetPointer(address);
-
- LPDIRECT3DTEXTURE9 source_texture = bFromZBuffer ? FramebufferManager::GetEFBDepthTexture() : FramebufferManager::GetEFBColorTexture();
- int width = (source.right - source.left) >> bScaleByHalf;
- int height = (source.bottom - source.top) >> bScaleByHalf;
-
- int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format);
-
- // Invalidate any existing texture covering this memory range.
- // TODO - don't delete the texture if it already exists, just replace the contents.
- TextureCache::InvalidateRange(address, size_in_bytes);
-
- u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
- u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
- u16 samples = TextureConversionShader::GetEncodedSampleCount(format);
-
- // only copy on cache line boundaries
- // extra pixels are copied but not displayed in the resulting texture
- s32 expandedWidth = (width + blkW) & (~blkW);
- s32 expandedHeight = (height + blkH) & (~blkH);
-
- float sampleStride = bScaleByHalf ? 2.f : 1.f;
- TextureConversionShader::SetShaderParameters(
- (float)expandedWidth,
- (float)Renderer::EFBToScaledY(expandedHeight), // TODO: Why do we scale this?
- (float)Renderer::EFBToScaledX(source.left),
- (float)Renderer::EFBToScaledY(source.top),
- Renderer::EFBToScaledXf(sampleStride),
- Renderer::EFBToScaledYf(sampleStride),
- (float)Renderer::GetTargetWidth(),
- (float)Renderer::GetTargetHeight());
-
- TargetRectangle scaledSource;
- scaledSource.top = 0;
- scaledSource.bottom = expandedHeight;
- scaledSource.left = 0;
- scaledSource.right = expandedWidth / samples;
- int cacheBytes = 32;
- if ((format & 0x0f) == 6)
- cacheBytes = 64;
-
- int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
- g_renderer->ResetAPIState();
- EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0,1.0f);
- D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
- D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
- g_renderer->RestoreAPIState();
-}
-
-u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
+int EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
{
u32 format = copyfmt;
@@ -440,16 +371,7 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 So
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0,1.0f);
- u64 hash = GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
- if (g_ActiveConfig.bEFBCopyCacheEnable)
- {
- // If the texture in RAM is already in the texture cache, do not copy it again as it has not changed.
- if (TextureCache::Find(address, hash))
- return hash;
- }
-
- TextureCache::MakeRangeDynamic(address,size_in_bytes);
- return hash;
+ return size_in_bytes; // TODO: D3D11 is calculating this value differently!
}
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight,float Gamma)
@@ -490,7 +412,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE
destTexture->GetSurfaceLevel(0,&Rendersurf);
D3D::dev->SetDepthStencilSurface(NULL);
D3D::dev->SetRenderTarget(0, Rendersurf);
-
+
D3DVIEWPORT9 vp;
// Stretch picture with increased internal resolution
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.h b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.h
index aa4757e4c9..4036f21447 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.h
@@ -35,15 +35,13 @@ namespace TextureConverter
void Init();
void Shutdown();
-void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
- u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
-
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc,
u8* destAddr, int dstWidth, int dstHeight,float Gamma);
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE9 destTexture);
-u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
+// returns size of the encoded data (in bytes)
+int EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture, u32 SourceW, u32 SourceH, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
}
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp
index d9c33b67ef..2083d4f1d8 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp
@@ -137,12 +137,13 @@ void VertexManager::vFlush()
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
tex.texTlut[i&3].tlut_format,
(tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips,
- (tex.texMode1[i&3].max_lod >> 4));
+ tex.texMode1[i&3].max_lod >> 4,
+ tex.texImage1[i&3].image_type);
if (tentry)
{
// 0s are probably for no manual wrapping needed.
- PixelShaderManager::SetTexDims(i, tentry->realW, tentry->realH, 0, 0);
+ PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, tentry->virtual_width, tentry->virtual_height, 0, 0, API_D3D9);
}
else
ERROR_LOG(VIDEO, "error loading texture");
@@ -151,7 +152,7 @@ void VertexManager::vFlush()
// set global constants
VertexShaderManager::SetConstants();
- PixelShaderManager::SetConstants();
+ PixelShaderManager::SetConstants(API_D3D9);
if (!PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components))
{
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp
index 5fc2b6dee2..e392cf3de0 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp
@@ -38,6 +38,7 @@ namespace DX9
VertexShaderCache::VSCache VertexShaderCache::vshaders;
const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
+VERTEXSHADERUID VertexShaderCache::last_uid;
#define MAX_SSAA_SHADERS 3
@@ -151,6 +152,11 @@ void VertexShaderCache::Init()
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
VertexShaderCacheInserter inserter;
g_vs_disk_cache.OpenAndRead(cache_filename, inserter);
+
+ if (g_Config.bEnableShaderDebugging)
+ Clear();
+
+ last_entry = NULL;
}
void VertexShaderCache::Clear()
@@ -159,7 +165,7 @@ void VertexShaderCache::Clear()
iter->second.Destroy();
vshaders.clear();
- memset(&last_vertex_shader_uid, 0xFF, sizeof(last_vertex_shader_uid));
+ last_entry = NULL;
}
void VertexShaderCache::Shutdown()
@@ -184,23 +190,27 @@ bool VertexShaderCache::SetShader(u32 components)
{
VERTEXSHADERUID uid;
GetVertexShaderId(&uid, components);
- if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
+ if (last_entry)
{
- GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
- return (vshaders[uid].shader != NULL);
+ if (uid == last_uid)
+ {
+ GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
+ ValidateVertexShaderIDs(API_D3D9, last_entry->safe_uid, last_entry->code, components);
+ return (last_entry->shader != NULL);
+ }
}
- memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
+ last_uid = uid;
VSCache::iterator iter = vshaders.find(uid);
if (iter != vshaders.end())
{
- iter->second.frameCount = frameCount;
const VSCacheEntry &entry = iter->second;
last_entry = &entry;
if (entry.shader) D3D::SetVertexShader(entry.shader);
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
+ ValidateVertexShaderIDs(API_D3D9, entry.safe_uid, entry.code, components);
return (entry.shader != NULL);
}
@@ -213,12 +223,16 @@ bool VertexShaderCache::SetShader(u32 components)
return false;
}
g_vs_disk_cache.Append(uid, bytecode, bytecodelen);
- g_vs_disk_cache.Sync();
- bool result = InsertByteCode(uid, bytecode, bytecodelen, true);
+ bool success = InsertByteCode(uid, bytecode, bytecodelen, true);
+ if (g_ActiveConfig.bEnableShaderDebugging && success)
+ {
+ vshaders[uid].code = code;
+ GetSafeVertexShaderId(&vshaders[uid].safe_uid, components);
+ }
delete [] bytecode;
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
- return result;
+ return success;
}
bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate) {
@@ -227,7 +241,6 @@ bool VertexShaderCache::InsertByteCode(const VERTEXSHADERUID &uid, const u8 *byt
// Make an entry in the table
VSCacheEntry entry;
entry.shader = shader;
- entry.frameCount = frameCount;
vshaders[uid] = entry;
last_entry = &vshaders[uid];
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h
index b516f46f9a..c9c447e35b 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h
@@ -34,11 +34,11 @@ private:
struct VSCacheEntry
{
LPDIRECT3DVERTEXSHADER9 shader;
- int frameCount;
-#if defined(_DEBUG) || defined(DEBUGFAST)
+
std::string code;
-#endif
- VSCacheEntry() : shader(NULL), frameCount(0) {}
+ VERTEXSHADERUIDSAFE safe_uid;
+
+ VSCacheEntry() : shader(NULL) {}
void Destroy()
{
if (shader)
@@ -51,6 +51,7 @@ private:
static VSCache vshaders;
static const VSCacheEntry *last_entry;
+ static VERTEXSHADERUID last_uid;
static void Clear();
public:
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp
index 1d733f7dc3..6c52219f97 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp
@@ -78,7 +78,7 @@ void VideoBackend::UpdateFPSDisplay(const char *text)
{
TCHAR temp[512];
swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text);
- SetWindowText(EmuWindow::GetWnd(), temp);
+ EmuWindow::SetWindowText(temp);
}
std::string VideoBackend::GetName()
@@ -132,6 +132,7 @@ void VideoBackend::ShowConfig(void* parent)
bool VideoBackend::Initialize(void *&window_handle)
{
+ InitializeShared();
InitBackendInfo();
frameCount = 0;
diff --git a/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt b/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt
index c57106645f..b506087106 100644
--- a/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt
+++ b/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt
@@ -22,8 +22,10 @@ if(wxWidgets_FOUND)
set(LIBS ${LIBS} ${wxWidgets_LIBRARIES})
endif(wxWidgets_FOUND)
-if(APPLE OR WIN32 OR ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+if(WIN32 OR ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(LIBS ${LIBS} Cg CgGL)
+elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+ list(APPEND LIBS "${CMAKE_SOURCE_DIR}/Externals/Cg/Cg.framework")
endif()
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
diff --git a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj
index d12f779d53..f782fd2c93 100644
--- a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj
+++ b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj
@@ -46,7 +46,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -57,7 +57,6 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp
index bedcaa6245..cbdb702885 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp
@@ -73,8 +73,9 @@ void OpenGL_SetWindowText(const char *text)
#elif defined(__APPLE__)
[GLWin.cocoaWin setTitle: [NSString stringWithUTF8String: text]];
#elif defined(_WIN32)
- // TODO convert text to unicode and change SetWindowTextA to SetWindowText
- SetWindowTextA(EmuWindow::GetWnd(), text);
+ TCHAR temp[512];
+ swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs"), text);
+ EmuWindow::SetWindowText(temp);
#elif defined(HAVE_X11) && HAVE_X11
// Tell X to ask the window manager to set the window title.
// (X itself doesn't provide window title functionality.)
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp
index fb4c226f77..61e41008b3 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp
@@ -44,7 +44,8 @@ bool PixelShaderCache::s_displayCompileAlert;
GLuint PixelShaderCache::CurrentShader;
bool PixelShaderCache::ShaderEnabled;
-static FRAGMENTSHADER* pShaderLast = NULL;
+PixelShaderCache::PSCacheEntry* PixelShaderCache::last_entry = NULL;
+PIXELSHADERUID PixelShaderCache::last_uid;
GLuint PixelShaderCache::GetDepthMatrixProgram()
{
@@ -61,10 +62,9 @@ void PixelShaderCache::Init()
glEnable(GL_FRAGMENT_PROGRAM_ARB);
ShaderEnabled = true;
CurrentShader = 0;
+ last_entry = NULL;
GL_REPORT_ERRORD();
- memset(&last_pixel_shader_uid, 0xFF, sizeof(last_pixel_shader_uid));
-
s_displayCompileAlert = true;
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, (GLint *)&s_nMaxPixelInstructions);
@@ -184,38 +184,43 @@ void PixelShaderCache::Shutdown()
FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
{
PIXELSHADERUID uid;
- GetPixelShaderId(&uid, dstAlphaMode);
-
+ GetPixelShaderId(&uid, dstAlphaMode, components);
+
// Check if the shader is already set
- if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
+ if (last_entry)
{
- GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
- return pShaderLast;
+ if (uid == last_uid)
+ {
+ GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
+ ValidatePixelShaderIDs(API_OPENGL, last_entry->safe_uid, last_entry->shader.strprog, dstAlphaMode, components);
+ return &last_entry->shader;
+ }
}
- memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
+ last_uid = uid;
PSCache::iterator iter = PixelShaders.find(uid);
-
if (iter != PixelShaders.end())
{
- iter->second.frameCount = frameCount;
PSCacheEntry &entry = iter->second;
- if (&entry.shader != pShaderLast)
- {
- pShaderLast = &entry.shader;
- }
+ last_entry = &entry;
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
- return pShaderLast;
+ ValidatePixelShaderIDs(API_OPENGL, entry.safe_uid, entry.shader.strprog, dstAlphaMode, components);
+ return &last_entry->shader;
}
// Make an entry in the table
PSCacheEntry& newentry = PixelShaders[uid];
- newentry.frameCount = frameCount;
- pShaderLast = &newentry.shader;
+ last_entry = &newentry;
const char *code = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components);
+ if (g_ActiveConfig.bEnableShaderDebugging && code)
+ {
+ GetSafePixelShaderId(&newentry.safe_uid, dstAlphaMode, components);
+ newentry.shader.strprog = code;
+ }
+
#if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
static int counter = 0;
@@ -234,7 +239,7 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp
INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
- return pShaderLast;
+ return &last_entry->shader;
}
bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram)
@@ -247,7 +252,7 @@ bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrpr
#if defined HAVE_CG && HAVE_CG
char stropt[128];
- sprintf(stropt, "MaxLocalParams=32,NumInstructionSlots=%d", s_nMaxPixelInstructions);
+ sprintf(stropt, "MaxLocalParams=224,NumInstructionSlots=%d", s_nMaxPixelInstructions);
const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL};
CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts);
@@ -318,9 +323,6 @@ bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrpr
cgDestroyProgram(tempprog);
#endif
-#if defined(_DEBUG) || defined(DEBUGFAST)
- ps.strprog = pstrprogram;
-#endif
return true;
}
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h
index f404b206a2..f528eeb35b 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h
@@ -39,9 +39,7 @@ struct FRAGMENTSHADER
}
}
GLuint glprogid; // opengl program id
-#if defined(_DEBUG) || defined(DEBUGFAST)
std::string strprog;
-#endif
};
class PixelShaderCache
@@ -49,13 +47,13 @@ class PixelShaderCache
struct PSCacheEntry
{
FRAGMENTSHADER shader;
- int frameCount;
- PSCacheEntry() : frameCount(0) {}
+ PSCacheEntry() {}
~PSCacheEntry() {}
void Destroy()
{
shader.Destroy();
}
+ PIXELSHADERUIDSAFE safe_uid;
};
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
@@ -67,6 +65,8 @@ class PixelShaderCache
static bool s_displayCompileAlert;
static GLuint CurrentShader;
+ static PSCacheEntry* last_entry;
+ static PIXELSHADERUID last_uid;
static bool ShaderEnabled;
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
index 0c9d904cad..9883d35fbb 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
@@ -60,6 +60,7 @@
#include "Core.h"
#include "Movie.h"
#include "Host.h"
+#include "BPFunctions.h"
#include "main.h" // Local
#ifdef _WIN32
@@ -109,12 +110,6 @@ int s_fps=0;
RasterFont* s_pfont = NULL;
-#if defined _WIN32 || defined HAVE_LIBAV
-static bool s_bAVIDumping = false;
-#else
-static File::IOFile f_pFrameDump;
-#endif
-
// 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
static int s_MSAASamples = 1;
static int s_MSAACoverageSamples = 0;
@@ -128,6 +123,12 @@ static u32 s_blendMode;
static std::thread scrshotThread;
#endif
+// EFB cache related
+const u32 EFB_CACHE_RECT_SIZE = 64; // Cache 64x64 blocks.
+const u32 EFB_CACHE_WIDTH = (EFB_WIDTH + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE; // round up
+const u32 EFB_CACHE_HEIGHT = (EFB_HEIGHT + EFB_CACHE_RECT_SIZE - 1) / EFB_CACHE_RECT_SIZE;
+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] =
{
@@ -249,9 +250,6 @@ Renderer::Renderer()
s_fps=0;
s_blendMode = 0;
-#if defined _WIN32 || defined HAVE_LIBAV
- s_bAVIDumping = false;
-#endif
#if defined HAVE_CG && HAVE_CG
g_cgcontext = cgCreateContext();
@@ -515,19 +513,6 @@ Renderer::~Renderer()
#endif
delete g_framebuffer_manager;
-
-#if defined _WIN32 || defined HAVE_LIBAV
- if(s_bAVIDumping)
- {
- AVIDump::Stop();
- s_bLastFrameDumped = false;
- s_bAVIDumping = false;
- }
-#else
- if (f_pFrameDump.IsOpen())
- f_pFrameDump.Close();
- s_bLastFrameDumped = false;
-#endif
}
// Create On-Screen-Messages
@@ -610,7 +595,7 @@ void Renderer::RenderText(const char *text, int left, int top, u32 color)
{
const int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth();
const int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight();
-
+
glColor4f(((color>>16) & 0xff)/255.0f, ((color>> 8) & 0xff)/255.0f,
((color>> 0) & 0xff)/255.0f, ((color>>24) & 0xFF)/255.0f);
@@ -642,49 +627,9 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
// Renderer::GetTargetHeight() = the fixed ini file setting
// donkopunchstania - it appears scissorBR is the bottom right pixel inside the scissor box
// therefore the width and height are (scissorBR + 1) - scissorTL
-bool Renderer::SetScissorRect()
+void Renderer::SetScissorRect(const TargetRectangle& rc)
{
- MathUtil::Rectangle<float> rc;
- GetScissorRect(rc);
-
- if (rc.left < 0) rc.left = 0;
- if (rc.top < 0) rc.top = 0;
- if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
- if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
-
- if (rc.left > rc.right)
- {
- int temp = rc.right;
- rc.right = rc.left;
- rc.left = temp;
- }
- if (rc.top > rc.bottom)
- {
- int temp = rc.bottom;
- rc.bottom = rc.top;
- rc.top = temp;
- }
-
- // Check that the coordinates are good
- if (rc.right != rc.left && rc.bottom != rc.top)
- {
- glScissor(
- EFBToScaledX(rc.left), // x = 0 for example
- EFBToScaledY(EFB_HEIGHT - rc.bottom), // y = 0 for example
- EFBToScaledX(rc.right - rc.left), // width = 640 for example
- EFBToScaledY(rc.bottom - rc.top)); // height = 480 for example
- return true;
- }
- else
- {
- glScissor(
- 0,
- 0,
- Renderer::GetTargetWidth(),
- Renderer::GetTargetHeight()
- );
- }
- return false;
+ glScissor(rc.left, rc.bottom, rc.GetWidth(), rc.GetHeight());
}
void Renderer::SetColorMask()
@@ -698,6 +643,42 @@ void Renderer::SetColorMask()
glColorMask(ColorMask, ColorMask, ColorMask, AlphaMask);
}
+void ClearEFBCache()
+{
+ for (u32 i = 0; i < EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT; ++i)
+ s_efbCacheValid[0][i] = false;
+
+ for (u32 i = 0; i < EFB_CACHE_WIDTH * EFB_CACHE_HEIGHT; ++i)
+ s_efbCacheValid[1][i] = false;
+}
+
+void Renderer::UpdateEFBCache(EFBAccessType type, u32 cacheRectIdx, const EFBRectangle& efbPixelRc, const TargetRectangle& targetPixelRc, const u32* data)
+{
+ u32 cacheType = (type == PEEK_Z ? 0 : 1);
+
+ if (!s_efbCache[cacheType][cacheRectIdx].size())
+ s_efbCache[cacheType][cacheRectIdx].resize(EFB_CACHE_RECT_SIZE * EFB_CACHE_RECT_SIZE);
+
+ u32 targetPixelRcWidth = targetPixelRc.right - targetPixelRc.left;
+
+ for (u32 yCache = 0; yCache < EFB_CACHE_RECT_SIZE; ++yCache)
+ {
+ u32 yEFB = efbPixelRc.top + yCache;
+ u32 yPixel = (EFBToScaledY(EFB_HEIGHT - yEFB) + EFBToScaledY(EFB_HEIGHT - yEFB - 1)) / 2;
+ u32 yData = yPixel - targetPixelRc.bottom;
+
+ for (u32 xCache = 0; xCache < EFB_CACHE_RECT_SIZE; ++xCache)
+ {
+ u32 xEFB = efbPixelRc.left + xCache;
+ u32 xPixel = (EFBToScaledX(xEFB) + EFBToScaledX(xEFB + 1)) / 2;
+ u32 xData = xPixel - targetPixelRc.left;
+ s_efbCache[cacheType][cacheRectIdx][yCache * EFB_CACHE_RECT_SIZE + xCache] = data[yData * targetPixelRcWidth + xData];
+ }
+ }
+
+ s_efbCacheValid[cacheType][cacheRectIdx] = true;
+}
+
// This function allows the CPU to directly access the EFB.
// There are EFB peeks (which will read the color or depth of a pixel)
// and EFB pokes (which will change the color or depth of a pixel).
@@ -717,34 +698,50 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
if (!g_ActiveConfig.bEFBAccessEnable)
return 0;
- // Get the rectangular target region covered by the EFB pixel
+ u32 cacheRectIdx = (y / EFB_CACHE_RECT_SIZE) * EFB_CACHE_WIDTH
+ + (x / EFB_CACHE_RECT_SIZE);
+
+ // Get the rectangular target region containing the EFB pixel
EFBRectangle efbPixelRc;
- efbPixelRc.left = x;
- efbPixelRc.top = y;
- efbPixelRc.right = x + 1;
- efbPixelRc.bottom = y + 1;
+ efbPixelRc.left = (x / EFB_CACHE_RECT_SIZE) * EFB_CACHE_RECT_SIZE;
+ efbPixelRc.top = (y / EFB_CACHE_RECT_SIZE) * EFB_CACHE_RECT_SIZE;
+ efbPixelRc.right = efbPixelRc.left + EFB_CACHE_RECT_SIZE;
+ efbPixelRc.bottom = efbPixelRc.top + EFB_CACHE_RECT_SIZE;
TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc);
+ u32 targetPixelRcWidth = targetPixelRc.right - targetPixelRc.left;
+ u32 targetPixelRcHeight = targetPixelRc.top - targetPixelRc.bottom;
// TODO (FIX) : currently, AA path is broken/offset and doesn't return the correct pixel
switch (type)
{
case PEEK_Z:
{
- if (s_MSAASamples > 1)
+ u32 z;
+
+ if (!s_efbCacheValid[0][cacheRectIdx])
{
- // Resolve our rectangle.
- FramebufferManager::GetEFBDepthTexture(efbPixelRc);
- glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer());
- }
+ if (s_MSAASamples > 1)
+ {
+ // Resolve our rectangle.
+ FramebufferManager::GetEFBDepthTexture(efbPixelRc);
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer());
+ }
+
+ u32* depthMap = new u32[targetPixelRcWidth * targetPixelRcHeight];
- // Sample from the center of the target region.
- int srcX = (targetPixelRc.left + targetPixelRc.right) / 2;
- int srcY = (targetPixelRc.top + targetPixelRc.bottom) / 2;
+ glReadPixels(targetPixelRc.left, targetPixelRc.bottom, targetPixelRcWidth, targetPixelRcHeight,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, depthMap);
+ GL_REPORT_ERRORD();
- u32 z = 0;
- glReadPixels(srcX, srcY, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &z);
- GL_REPORT_ERRORD();
+ UpdateEFBCache(type, cacheRectIdx, efbPixelRc, targetPixelRc, depthMap);
+
+ delete[] depthMap;
+ }
+
+ u32 xRect = x % EFB_CACHE_RECT_SIZE;
+ u32 yRect = y % EFB_CACHE_RECT_SIZE;
+ z = s_efbCache[0][cacheRectIdx][yRect * EFB_CACHE_RECT_SIZE + xRect];
// Scale the 32-bit value returned by glReadPixels to a 24-bit
// value (GC uses a 24-bit Z-buffer).
@@ -769,21 +766,31 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
// determine if we're aiming at an enemy (0x80 / 0x88) or not (0x70)
// Wind Waker is also using it for the pictograph to determine the color of each pixel
- if (s_MSAASamples > 1)
+ u32 color;
+
+ if (!s_efbCacheValid[1][cacheRectIdx])
{
- // Resolve our rectangle.
- FramebufferManager::GetEFBColorTexture(efbPixelRc);
- glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer());
- }
+ if (s_MSAASamples > 1)
+ {
+ // Resolve our rectangle.
+ FramebufferManager::GetEFBColorTexture(efbPixelRc);
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, FramebufferManager::GetResolvedFramebuffer());
+ }
+
+ u32* colorMap = new u32[targetPixelRcWidth * targetPixelRcHeight];
+
+ glReadPixels(targetPixelRc.left, targetPixelRc.bottom, targetPixelRcWidth, targetPixelRcHeight,
+ GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, colorMap);
+ GL_REPORT_ERRORD();
- // Sample from the center of the target region.
- int srcX = (targetPixelRc.left + targetPixelRc.right) / 2;
- int srcY = (targetPixelRc.top + targetPixelRc.bottom) / 2;
+ UpdateEFBCache(type, cacheRectIdx, efbPixelRc, targetPixelRc, colorMap);
+
+ delete[] colorMap;
+ }
- // Read back pixel in BGRA format, then byteswap to get GameCube's ARGB Format.
- u32 color = 0;
- glReadPixels(srcX, srcY, 1, 1, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &color);
- GL_REPORT_ERRORD();
+ u32 xRect = x % EFB_CACHE_RECT_SIZE;
+ u32 yRect = y % EFB_CACHE_RECT_SIZE;
+ color = s_efbCache[1][cacheRectIdx][yRect * EFB_CACHE_RECT_SIZE + xRect];
// check what to do with the alpha channel (GX_PokeAlphaRead)
PixelEngine::UPEAlphaReadReg alpha_read_mode;
@@ -865,41 +872,35 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
{
ResetAPIState();
- GLenum ColorMask = GL_FALSE, AlphaMask = GL_FALSE;
- if (colorEnable) ColorMask = GL_TRUE;
- if (alphaEnable) AlphaMask = GL_TRUE;
- glColorMask(ColorMask, ColorMask, ColorMask, AlphaMask);
+ // color
+ GLboolean const
+ color_mask = colorEnable ? GL_TRUE : GL_FALSE,
+ alpha_mask = alphaEnable ? GL_TRUE : GL_FALSE;
+ glColorMask(color_mask, color_mask, color_mask, alpha_mask);
- if (zEnable)
- {
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
- glDepthFunc(GL_ALWAYS);
- }
- else
- {
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- glDepthFunc(GL_NEVER);
- }
+ glClearColor(
+ float((color >> 16) & 0xFF) / 255.0f,
+ float((color >> 8) & 0xFF) / 255.0f,
+ float((color >> 0) & 0xFF) / 255.0f,
+ float((color >> 24) & 0xFF) / 255.0f);
+
+ // depth
+ glDepthMask(zEnable ? GL_TRUE : GL_FALSE);
+
+ glClearDepth(float(z & 0xFFFFFF) / float(0xFFFFFF));
+
+ // Update rect for clearing the picture
+ glEnable(GL_SCISSOR_TEST);
+
+ TargetRectangle const targetRc = ConvertEFBRectangle(rc);
+ glScissor(targetRc.left, targetRc.bottom, targetRc.GetWidth(), targetRc.GetHeight());
- // Update viewport for clearing the picture
- TargetRectangle targetRc = ConvertEFBRectangle(rc);
- glViewport(targetRc.left, targetRc.bottom, targetRc.GetWidth(), targetRc.GetHeight());
- glDepthRange(0.0, (float)(z & 0xFFFFFF) / float(0xFFFFFF));
-
- glColor4f((float)((color >> 16) & 0xFF) / 255.0f,
- (float)((color >> 8) & 0xFF) / 255.0f,
- (float)(color & 0xFF) / 255.0f,
- (float)((color >> 24) & 0xFF) / 255.0f);
- glBegin(GL_QUADS);
- glVertex3f(-1.f, -1.f, 1.f);
- glVertex3f(-1.f, 1.f, 1.f);
- glVertex3f( 1.f, 1.f, 1.f);
- glVertex3f( 1.f, -1.f, 1.f);
- glEnd();
+ // glColorMask/glDepthMask/glScissor affect glClear (glViewport does not)
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RestoreAPIState();
+
+ ClearEFBCache();
}
void Renderer::ReinterpretPixelData(unsigned int convtype)
@@ -986,15 +987,14 @@ void Renderer::SetBlendMode(bool forceUpdate)
// This function has the final picture. We adjust the aspect ratio here.
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma)
{
- static u8 *data = NULL;
static int w = 0, h = 0;
if (g_bSkipCurrentFrame || (!XFBWrited && (!g_ActiveConfig.bUseXFB || !g_ActiveConfig.bUseRealXFB)) || !fbWidth || !fbHeight)
{
- if (g_ActiveConfig.bDumpFrames && data)
+ if (g_ActiveConfig.bDumpFrames && frame_data)
#ifdef _WIN32
- AVIDump::AddFrame((char *) data);
+ AVIDump::AddFrame(frame_data);
#elif defined HAVE_LIBAV
- AVIDump::AddFrame(data, w, h);
+ AVIDump::AddFrame((u8*)frame_data, w, h);
#endif
Core::Callback_VideoCopiedToXFB(false);
return;
@@ -1008,12 +1008,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
{
- if (g_ActiveConfig.bDumpFrames && data)
- #ifdef _WIN32
- AVIDump::AddFrame((char *) data);
- #elif defined HAVE_LIBAV
- AVIDump::AddFrame(data, w, h);
- #endif
+ if (g_ActiveConfig.bDumpFrames && frame_data)
+ {
+#ifdef _WIN32
+ AVIDump::AddFrame(frame_data);
+#elif defined HAVE_LIBAV
+ AVIDump::AddFrame((u8*)frame_data, w, h);
+#endif
+ }
Core::Callback_VideoCopiedToXFB(false);
return;
}
@@ -1172,26 +1174,26 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
if (g_ActiveConfig.bDumpFrames)
{
std::lock_guard<std::mutex> lk(s_criticalScreenshot);
- if (!data || w != dst_rect.GetWidth() ||
+ if (!frame_data || w != dst_rect.GetWidth() ||
h != dst_rect.GetHeight())
{
- if (data) delete[] data;
+ if (frame_data) delete[] frame_data;
w = dst_rect.GetWidth();
h = dst_rect.GetHeight();
- data = new u8[3 * w * h];
+ frame_data = new char[3 * w * h];
}
glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
+ glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data);
if (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0)
{
- if (!s_bLastFrameDumped)
+ if (!bLastFrameDumped)
{
#ifdef _WIN32
- s_bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), w, h);
+ bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), w, h);
#else
- s_bAVIDumping = AVIDump::Start(w, h);
+ bAVIDumping = AVIDump::Start(w, h);
#endif
- if (!s_bAVIDumping)
+ if (!bAVIDumping)
OSD::AddMessage("AVIDump Start failed", 2000);
else
{
@@ -1200,36 +1202,36 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), w, h).c_str(), 2000);
}
}
- if (s_bAVIDumping)
+ if (bAVIDumping)
{
#ifdef _WIN32
- AVIDump::AddFrame((char *) data);
+ AVIDump::AddFrame(frame_data);
#else
- FlipImageData(data, w, h);
- AVIDump::AddFrame(data, w, h);
+ FlipImageData((u8*)frame_data, w, h);
+ AVIDump::AddFrame((u8*)frame_data, w, h);
#endif
}
- s_bLastFrameDumped = true;
+ bLastFrameDumped = true;
}
else
NOTICE_LOG(VIDEO, "Error reading framebuffer");
}
else
{
- if (s_bLastFrameDumped && s_bAVIDumping)
+ if (bLastFrameDumped && bAVIDumping)
{
- if (data)
+ if (frame_data)
{
- delete[] data;
- data = NULL;
+ delete[] frame_data;
+ frame_data = NULL;
w = h = 0;
}
AVIDump::Stop();
- s_bAVIDumping = false;
+ bAVIDumping = false;
OSD::AddMessage("Stop dumping frames", 2000);
}
- s_bLastFrameDumped = false;
+ bLastFrameDumped = false;
}
#else
if (g_ActiveConfig.bDumpFrames)
@@ -1238,16 +1240,16 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
std::string movie_file_name;
w = dst_rect.GetWidth();
h = dst_rect.GetHeight();
- data = new u8[3 * w * h];
+ frame_data = new char[3 * w * h];
glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
+ glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data);
if (GL_REPORT_ERROR() == GL_NO_ERROR)
{
- if (!s_bLastFrameDumped)
+ if (!bLastFrameDumped)
{
movie_file_name = File::GetUserPath(D_DUMPFRAMES_IDX) + "framedump.raw";
- f_pFrameDump.Open(movie_file_name, "wb");
- if (!f_pFrameDump)
+ pFrameDump.Open(movie_file_name, "wb");
+ if (!pFrameDump)
OSD::AddMessage("Error opening framedump.raw for writing.", 2000);
else
{
@@ -1256,22 +1258,22 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
OSD::AddMessage(msg, 2000);
}
}
- if (f_pFrameDump)
+ if (pFrameDump)
{
- FlipImageData(data, w, h);
- f_pFrameDump.WriteBytes(data, w * 3 * h);
- f_pFrameDump.Flush();
+ FlipImageData((u8*)frame_data, w, h);
+ pFrameDump.WriteBytes(frame_data, w * 3 * h);
+ pFrameDump.Flush();
}
- s_bLastFrameDumped = true;
+ bLastFrameDumped = true;
}
- delete[] data;
+ delete[] frame_data;
}
else
{
- if (s_bLastFrameDumped)
- f_pFrameDump.Close();
- s_bLastFrameDumped = false;
+ if (bLastFrameDumped)
+ pFrameDump.Close();
+ bLastFrameDumped = false;
}
#endif
@@ -1392,8 +1394,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
g_Config.iSaveTargetId = 0;
// reload textures if these settings changed
- if (g_Config.bSafeTextureCache != g_ActiveConfig.bSafeTextureCache ||
- g_Config.bUseNativeMips != g_ActiveConfig.bUseNativeMips)
+ if (g_Config.bUseNativeMips != g_ActiveConfig.bUseNativeMips)
TextureCache::Invalidate(false);
if (g_Config.bCopyEFBToTexture != g_ActiveConfig.bCopyEFBToTexture)
@@ -1407,6 +1408,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// GetTargetWidth(), GetTargetHeight());
Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB));
XFBWrited = false;
+
+ // Invalidate EFB cache
+ ClearEFBCache();
}
// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing
@@ -1422,9 +1426,6 @@ void Renderer::ResetAPIState()
glDisable(GL_BLEND);
glDepthMask(GL_FALSE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
- // make sure to disable wireframe when drawing the clear quad
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
void Renderer::RestoreAPIState()
@@ -1432,14 +1433,13 @@ void Renderer::RestoreAPIState()
// Gets us back into a more game-like state.
glEnable(GL_SCISSOR_TEST);
SetGenerationMode();
- SetScissorRect();
+ BPFunctions::SetScissor();
SetColorMask();
SetDepthMode();
SetBlendMode(true);
VertexShaderManager::SetViewportChanged();
- if (g_ActiveConfig.bWireFrame)
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ glPolygonMode(GL_FRONT_AND_BACK, g_ActiveConfig.bWireFrame ? GL_LINE : GL_FILL);
VertexShaderCache::SetCurrentShader(0);
PixelShaderCache::SetCurrentShader(0);
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.h b/Source/Plugins/Plugin_VideoOGL/Src/Render.h
index 5805c524ae..9cf1573b56 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/Render.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.h
@@ -7,6 +7,8 @@
namespace OGL
{
+void ClearEFBCache();
+
class Renderer : public ::Renderer
{
public:
@@ -15,7 +17,7 @@ public:
void SetColorMask();
void SetBlendMode(bool forceUpdate);
- bool SetScissorRect();
+ void SetScissorRect(const TargetRectangle& rc);
void SetGenerationMode();
void SetDepthMode();
void SetLogicOpMode();
@@ -57,6 +59,9 @@ public:
void SetVSConstant4fv(unsigned int const_number, const float *f);
void SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f);
void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f);
+
+private:
+ void UpdateEFBCache(EFBAccessType type, u32 cacheRectIdx, const EFBRectangle& efbPixelRc, const TargetRectangle& targetPixelRc, const u32* data);
};
}
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp
index 4a9431a563..f78eb11905 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp
@@ -39,6 +39,7 @@
#include "Globals.h"
#include "Hash.h"
#include "HiresTextures.h"
+#include "HW/Memmap.h"
#include "ImageWrite.h"
#include "MemoryUtil.h"
#include "PixelShaderCache.h"
@@ -124,7 +125,7 @@ bool TextureCache::TCacheEntry::Save(const char filename[])
std::string tga_filename(filename);
tga_filename.replace(tga_filename.size() - 3, 3, "tga");
- return SaveTexture(tga_filename.c_str(), GL_TEXTURE_2D, texture, realW, realH);
+ return SaveTexture(tga_filename.c_str(), GL_TEXTURE_2D, texture, virtual_width, virtual_height);
}
TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width,
@@ -278,7 +279,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
GL_REPORT_ERRORD();
- if (false == isDynamic || g_ActiveConfig.bCopyEFBToTexture)
+ if (type != TCET_EC_DYNAMIC || g_ActiveConfig.bCopyEFBToTexture)
{
if (s_TempFramebuffer == 0)
glGenFramebuffersEXT(1, (GLuint*)&s_TempFramebuffer);
@@ -294,7 +295,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, read_texture);
- glViewport(0, 0, virtualW, virtualH);
+ glViewport(0, 0, virtual_width, virtual_height);
PixelShaderCache::SetCurrentShader((srcFormat == PIXELFMT_Z24) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram());
PixelShaderManager::SetColorMatrix(colmat); // set transformation
@@ -317,7 +318,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
if (false == g_ActiveConfig.bCopyEFBToTexture)
{
- hash = TextureConverter::EncodeToRamFromTexture(
+ int encoded_size = TextureConverter::EncodeToRamFromTexture(
addr,
read_texture,
srcFormat == PIXELFMT_Z24,
@@ -325,6 +326,15 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
dstFormat,
scaleByHalf,
srcRect);
+
+ u8* dst = Memory::GetPointer(addr);
+ hash = GetHash64(dst,encoded_size,g_ActiveConfig.iSafeTextureCache_ColorSamples);
+
+ // Mark texture entries in destination address range dynamic unless caching is enabled and the texture entry is up to date
+ if (!g_ActiveConfig.bEFBCopyCacheEnable)
+ TextureCache::MakeRangeDynamic(addr,encoded_size);
+ else if (!TextureCache::Find(addr, hash))
+ TextureCache::MakeRangeDynamic(addr,encoded_size);
}
FramebufferManager::SetFramebuffer(0);
@@ -337,7 +347,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
{
static int count = 0;
SaveTexture(StringFromFormat("%sefb_frame_%i.tga", File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
- count++).c_str(), GL_TEXTURE_2D, texture, realW, realH);
+ count++).c_str(), GL_TEXTURE_2D, texture, virtual_width, virtual_height);
}
}
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp
index c715775194..c73d3abdbf 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp
@@ -250,78 +250,7 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
}
-void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
-{
- u32 format = copyfmt;
-
- if (bFromZBuffer)
- {
- format |= _GX_TF_ZTF;
- if (copyfmt == 11)
- format = GX_TF_Z16;
- else if (format < GX_TF_Z8 || format > GX_TF_Z24X8)
- format |= _GX_TF_CTF;
- }
- else
- if (copyfmt > GX_TF_RGBA8 || (copyfmt < GX_TF_RGB565 && !bIsIntensityFmt))
- format |= _GX_TF_CTF;
-
- FRAGMENTSHADER& texconv_shader = GetOrCreateEncodingShader(format);
- if (texconv_shader.glprogid == 0)
- return;
-
- u8 *dest_ptr = Memory::GetPointer(address);
-
- GLuint source_texture = bFromZBuffer ? FramebufferManager::ResolveAndGetDepthTarget(source) : FramebufferManager::ResolveAndGetRenderTarget(source);
-
- int width = (source.right - source.left) >> bScaleByHalf;
- int height = (source.bottom - source.top) >> bScaleByHalf;
-
- int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format);
-
- // Invalidate any existing texture covering this memory range.
- // TODO - don't delete the texture if it already exists, just replace the contents.
- TextureCache::InvalidateRange(address, size_in_bytes);
-
- u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
- u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
- u16 samples = TextureConversionShader::GetEncodedSampleCount(format);
-
- // only copy on cache line boundaries
- // extra pixels are copied but not displayed in the resulting texture
- s32 expandedWidth = (width + blkW) & (~blkW);
- s32 expandedHeight = (height + blkH) & (~blkH);
-
- float sampleStride = bScaleByHalf ? 2.f : 1.f;
- TextureConversionShader::SetShaderParameters(
- (float)expandedWidth,
- (float)Renderer::EFBToScaledY(expandedHeight), // TODO: Why do we scale this?
- (float)Renderer::EFBToScaledX(source.left),
- (float)Renderer::EFBToScaledY(EFB_HEIGHT - source.top - expandedHeight),
- Renderer::EFBToScaledXf(sampleStride),
- Renderer::EFBToScaledYf(sampleStride));
-
- TargetRectangle scaledSource;
- scaledSource.top = 0;
- scaledSource.bottom = expandedHeight;
- scaledSource.left = 0;
- scaledSource.right = expandedWidth / samples;
- int cacheBytes = 32;
- if ((format & 0x0f) == 6)
- cacheBytes = 64;
-
- int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
- g_renderer->ResetAPIState();
- EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
- FramebufferManager::SetFramebuffer(0);
- VertexShaderManager::SetViewportChanged();
- glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
- TextureCache::DisableStage(0);
- g_renderer->RestoreAPIState();
- GL_REPORT_ERRORD();
-}
-
-u64 EncodeToRamFromTexture(u32 address,GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
+int EncodeToRamFromTexture(u32 address,GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
{
u32 format = copyfmt;
@@ -379,19 +308,8 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture, bool bFromZBuffer,
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource,
dest_ptr, expandedWidth / samples, expandedHeight, readStride,
true, bScaleByHalf > 0 && !bFromZBuffer);
+ return size_in_bytes; // TODO: D3D11 is calculating this value differently!
- u64 hash = GetHash64(dest_ptr, size_in_bytes,
- g_ActiveConfig.iSafeTextureCache_ColorSamples);
- if (g_ActiveConfig.bEFBCopyCacheEnable)
- {
- // If the texture in RAM is already in the texture cache,
- // do not copy it again as it has not changed.
- if (TextureCache::Find(address, hash))
- return hash;
- }
-
- TextureCache::MakeRangeDynamic(address,size_in_bytes);
- return hash;
}
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight)
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h
index 719ac1b7fc..4113778603 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.h
@@ -32,15 +32,13 @@ namespace TextureConverter
void Init();
void Shutdown();
-void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
- u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
-
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
u8* destAddr, int dstWidth, int dstHeight);
void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTexture);
-u64 EncodeToRamFromTexture(u32 address, GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
+// returns size of the encoded data (in bytes)
+int EncodeToRamFromTexture(u32 address, GLuint source_texture, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
}
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp
index a101d6c2d6..5117f6ddb6 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp
@@ -155,12 +155,13 @@ void VertexManager::vFlush()
tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
tex.texTlut[i&3].tlut_format,
(tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips,
- (tex.texMode1[i&3].max_lod >> 4));
+ tex.texMode1[i&3].max_lod >> 4,
+ tex.texImage1[i&3].image_type);
if (tentry)
{
// 0s are probably for no manual wrapping needed.
- PixelShaderManager::SetTexDims(i, tentry->realW, tentry->realH, 0, 0);
+ PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, tentry->virtual_width, tentry->virtual_height, 0, 0, API_OPENGL);
if (g_ActiveConfig.iLog & CONF_SAVETEXTURES)
{
@@ -178,7 +179,7 @@ void VertexManager::vFlush()
// set global constants
VertexShaderManager::SetConstants();
- PixelShaderManager::SetConstants();
+ PixelShaderManager::SetConstants(API_OPENGL);
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate
&& bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
@@ -268,6 +269,8 @@ void VertexManager::vFlush()
#endif
g_Config.iSaveTargetId++;
+ ClearEFBCache();
+
GL_REPORT_ERRORD();
}
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp
index 96f2d5a2ae..dbbb7ee29b 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp
@@ -41,7 +41,9 @@ VertexShaderCache::VSCache VertexShaderCache::vshaders;
GLuint VertexShaderCache::CurrentShader;
bool VertexShaderCache::ShaderEnabled;
-static VERTEXSHADER *pShaderLast = NULL;
+VertexShaderCache::VSCacheEntry* VertexShaderCache::last_entry = NULL;
+VERTEXSHADERUID VertexShaderCache::last_uid;
+
static int s_nMaxVertexInstructions;
@@ -50,7 +52,7 @@ void VertexShaderCache::Init()
glEnable(GL_VERTEX_PROGRAM_ARB);
ShaderEnabled = true;
CurrentShader = 0;
- memset(&last_vertex_shader_uid, 0xFF, sizeof(last_vertex_shader_uid));
+ last_entry = NULL;
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&s_nMaxVertexInstructions);
if (strstr((const char*)glGetString(GL_VENDOR), "Humper") != NULL) s_nMaxVertexInstructions = 4096;
@@ -74,31 +76,34 @@ VERTEXSHADER* VertexShaderCache::SetShader(u32 components)
{
VERTEXSHADERUID uid;
GetVertexShaderId(&uid, components);
- if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
+ if (last_entry)
{
- GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
- return pShaderLast;
+ if (uid == last_uid)
+ {
+ GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
+ ValidateVertexShaderIDs(API_OPENGL, vshaders[uid].safe_uid, vshaders[uid].shader.strprog, components);
+ return &last_entry->shader;
+ }
}
- memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
+
+ last_uid = uid;
VSCache::iterator iter = vshaders.find(uid);
if (iter != vshaders.end())
{
- iter->second.frameCount = frameCount;
VSCacheEntry &entry = iter->second;
- if (&entry.shader != pShaderLast) {
- pShaderLast = &entry.shader;
- }
+ last_entry = &entry;
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
- return pShaderLast;
+ ValidateVertexShaderIDs(API_OPENGL, entry.safe_uid, entry.shader.strprog, components);
+ return &last_entry->shader;
}
// Make an entry in the table
VSCacheEntry& entry = vshaders[uid];
- entry.frameCount = frameCount;
- pShaderLast = &entry.shader;
+ last_entry = &entry;
const char *code = GenerateVertexShaderCode(components, API_OPENGL);
+ GetSafeVertexShaderId(&entry.safe_uid, components);
#if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
@@ -118,7 +123,7 @@ VERTEXSHADER* VertexShaderCache::SetShader(u32 components)
INCSTAT(stats.numVertexShadersCreated);
SETSTAT(stats.numVertexShadersAlive, vshaders.size());
GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true);
- return pShaderLast;
+ return &last_entry->shader;
}
bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram)
@@ -182,9 +187,8 @@ bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrpr
cgDestroyProgram(tempprog);
#endif
-#if defined(_DEBUG) || defined(DEBUGFAST)
- vs.strprog = pstrprogram;
-#endif
+ if (g_ActiveConfig.bEnableShaderDebugging)
+ vs.strprog = pstrprogram;
return true;
}
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h
index e311fde77b..6f4cbe25c2 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.h
@@ -32,9 +32,7 @@ struct VERTEXSHADER
VERTEXSHADER() : glprogid(0) {}
GLuint glprogid; // opengl program id
-#if defined(_DEBUG) || defined(DEBUGFAST)
std::string strprog;
-#endif
};
class VertexShaderCache
@@ -42,8 +40,8 @@ class VertexShaderCache
struct VSCacheEntry
{
VERTEXSHADER shader;
- int frameCount;
- VSCacheEntry() : frameCount(0) {}
+ VERTEXSHADERUIDSAFE safe_uid;
+ VSCacheEntry() {}
void Destroy() {
// printf("Destroying vs %i\n", shader.glprogid);
glDeleteProgramsARB(1, &shader.glprogid);
@@ -55,6 +53,9 @@ class VertexShaderCache
static VSCache vshaders;
+ static VSCacheEntry* last_entry;
+ static VERTEXSHADERUID last_uid;
+
static GLuint CurrentShader;
static bool ShaderEnabled;
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp
index a25f9cd839..251512fe6b 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp
@@ -155,6 +155,7 @@ void VideoBackend::ShowConfig(void *_hParent)
bool VideoBackend::Initialize(void *&window_handle)
{
+ InitializeShared();
InitBackendInfo();
frameCount = 0;
diff --git a/Source/Plugins/Plugin_VideoSoftware/Plugin_VideoSoftware.vcxproj b/Source/Plugins/Plugin_VideoSoftware/Plugin_VideoSoftware.vcxproj
index 26ccad4175..db6f072f20 100644
--- a/Source/Plugins/Plugin_VideoSoftware/Plugin_VideoSoftware.vcxproj
+++ b/Source/Plugins/Plugin_VideoSoftware/Plugin_VideoSoftware.vcxproj
@@ -46,13 +46,12 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">
<ConfigurationType>StaticLibrary</ConfigurationType>
diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp
index 404424f634..95ec555181 100644
--- a/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp
+++ b/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp
@@ -101,14 +101,14 @@ void SWBPWritten(int address, int newvalue)
// TODO - figure out a cleaner way.
if (Core::g_CoreStartupParameter.bWii)
- ptr = Memory::GetPointer(bpmem.tlutXferSrc << 5);
+ ptr = Memory::GetPointer(bpmem.tmem_config.tlut_src << 5);
else
- ptr = Memory::GetPointer((bpmem.tlutXferSrc & 0xFFFFF) << 5);
+ ptr = Memory::GetPointer((bpmem.tmem_config.tlut_src & 0xFFFFF) << 5);
if (ptr)
memcpy_gc(texMem + tlutTMemAddr, ptr, tlutXferCount);
else
- PanicAlert("Invalid palette pointer %08x %08x %08x", bpmem.tlutXferSrc, bpmem.tlutXferSrc << 5, (bpmem.tlutXferSrc & 0xFFFFF)<< 5);
+ PanicAlert("Invalid palette pointer %08x %08x %08x", bpmem.tmem_config.tlut_src, bpmem.tmem_config.tlut_src << 5, (bpmem.tmem_config.tlut_src & 0xFFFFF)<< 5);
break;
}
diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp
index abfd9155f5..c591bd0957 100644
--- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp
+++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp
@@ -215,6 +215,12 @@ bool VideoSoftware::Video_IsPossibleWaitingSetDrawDone(void)
return false;
}
+bool VideoSoftware::Video_IsHiWatermarkActive(void)
+{
+ return false;
+}
+
+
void VideoSoftware::Video_AbortFrame(void)
{
}
diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h
index 08b4c155ad..7c52e34291 100644
--- a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h
+++ b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h
@@ -36,7 +36,7 @@ class VideoSoftware : public VideoBackend
void Video_SetRendering(bool bEnabled);
void Video_GatherPipeBursted();
-
+ bool Video_IsHiWatermarkActive();
bool Video_IsPossibleWaitingSetDrawDone();
void Video_AbortFrame();