Merge 'master' into shader-uids-awesome.

Conflicts:
	Source/Core/VideoCommon/Src/LightingShaderGen.cpp
	Source/Core/VideoCommon/Src/PixelShaderGen.cpp
	Source/Core/VideoCommon/Src/PixelShaderGen.h
	Source/Core/VideoCommon/Src/VertexShaderGen.cpp
This commit is contained in:
NeoBrainX
2013-06-17 12:05:47 +02:00
172 changed files with 4585 additions and 1736 deletions

View File

@ -4,6 +4,7 @@ set(SRCS Src/BPFunctions.cpp
Src/CPMemory.cpp
Src/CommandProcessor.cpp
Src/Debugger.cpp
Src/DriverDetails.cpp
Src/Fifo.cpp
Src/FPSCounter.cpp
Src/FramebufferManagerBase.cpp

View File

@ -89,6 +89,19 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size
}
break;
case BPMEM_ZCOMPARE:
{
SetRegName(BPMEM_ZCOMPARE);
PE_CONTROL config; config.hex = cmddata;
const char* pixel_formats[] = { "RGB8_Z24", "RGBA6_Z24", "RGB565_Z16", "Z24", "Y8", "U8", "V8", "YUV420" };
const char* zformats[] = { "linear", "compressed (near)", "compressed (mid)", "compressed (far)", "inv linear", "compressed (inv near)", "compressed (inv mid)", "compressed (inv far)" };
snprintf(desc, desc_size, "EFB pixel format: %s\n"
"Depth format: %s\n"
"Early depth test: %s\n",
pixel_formats[config.pixel_format], zformats[config.zformat], no_yes[config.early_ztest]);
}
break;
case BPMEM_EFB_BR: // 0x4A
{
// TODO: Misleading name, should be BPMEM_EFB_WH instead
@ -162,6 +175,21 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size
// TODO: Description
break;
case BPMEM_TX_SETIMAGE3: // 0x94
case BPMEM_TX_SETIMAGE3+1:
case BPMEM_TX_SETIMAGE3+2:
case BPMEM_TX_SETIMAGE3+3:
case BPMEM_TX_SETIMAGE3_4: // 0xB4
case BPMEM_TX_SETIMAGE3_4+1:
case BPMEM_TX_SETIMAGE3_4+2:
case BPMEM_TX_SETIMAGE3_4+3:
{
SetRegName(BPMEM_TX_SETIMAGE3);
TexImage3 teximg; teximg.hex = cmddata;
snprintf(desc, desc_size, "Source address (32 byte aligned): 0x%06X", teximg.image_base << 5);
}
break;
case BPMEM_TEV_COLOR_ENV: // 0xC0
case BPMEM_TEV_COLOR_ENV+2:
case BPMEM_TEV_COLOR_ENV+4:

View File

@ -0,0 +1,69 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include <map>
#include "LogManager.h"
#include "DriverDetails.h"
namespace DriverDetails
{
struct BugInfo
{
Bug m_bug; // Which bug it is
u32 m_devfamily; // Which device(family) has the error
double m_versionstart; // When it started
double m_versionend; // When it ended
bool m_hasbug; // Does it have it?
};
// Local members
Vendor m_vendor = VENDOR_UNKNOWN;
u32 m_devfamily = 0;
double m_version = 0.0;
// This is a list of all known bugs for each vendor
// We use this to check if the device and driver has a issue
BugInfo m_qualcommbugs[] = {
{BUG_NODYNUBOACCESS, 300, 14.0, -1.0},
{BUG_BROKENCENTROID, 300, 14.0, -1.0},
};
std::map<std::pair<Vendor, Bug>, BugInfo> m_bugs;
// Private function
void InitBugMap()
{
switch(m_vendor)
{
case VENDOR_QUALCOMM:
for (int a = 0; a < (sizeof(m_qualcommbugs) / sizeof(BugInfo)); ++a)
m_bugs[std::make_pair(m_vendor, m_qualcommbugs[a].m_bug)] = m_qualcommbugs[a];
break;
default:
break;
}
}
void Init(Vendor vendor, const u32 devfamily, const double version)
{
m_vendor = vendor;
m_devfamily = devfamily;
m_version = version;
InitBugMap();
for (auto it = m_bugs.begin(); it != m_bugs.end(); ++it)
if (it->second.m_devfamily == m_devfamily)
if (it->second.m_versionend == -1.0 || (it->second.m_versionstart <= m_version && it->second.m_versionend > m_version))
it->second.m_hasbug = true;
}
const bool HasBug(Bug bug)
{
auto it = m_bugs.find(std::make_pair(m_vendor, bug));
if (it == m_bugs.end())
return false;
return it->second.m_hasbug;
}
}

View File

@ -0,0 +1,52 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#pragma once
#include "CommonTypes.h"
namespace DriverDetails
{
// Enum of known vendors
// Tegra and Nvidia are separated out due to such substantial differences
enum Vendor
{
VENDOR_NVIDIA = 0,
VENDOR_ATI,
VENDOR_INTEL,
VENDOR_ARM,
VENDOR_QUALCOMM,
VENDOR_IMGTEC,
VENDOR_TEGRA,
VENDOR_VIVANTE,
VENDOR_UNKNOWN
};
// Enum of known bugs
// These can be vendor specific, but we put them all in here
// For putting a new bug in here, make sure to put a detailed comment above the enum
// This'll ensure we know exactly what the issue is.
enum Bug
{
// Bug: No Dynamic UBO array object access
// Affected Devices: Qualcomm/Adreno
// Started Version: 14
// Ended Version: -1
// Accessing UBO array members dynamically causes the Adreno shader compiler to crash
// Errors out with "Internal Error"
BUG_NODYNUBOACCESS = 0,
// Bug: Centroid is broken in shaders
// Affected devices: Qualcomm/Adreno
// Started Version: 14
// Ended Version: -1
// Centroid in/out, used in the shaders, is used for multisample buffers to get the texel correctly
// When MSAA is disabled, it acts like a regular in/out
// Tends to cause the driver to render full white or black
BUG_BROKENCENTROID,
};
// Initializes our internal vendor, device family, and driver version
void Init(Vendor vendor, const u32 devfamily, const double version);
// Once Vendor and driver version is set, this will return if it has the applicable bug passed to it.
const bool HasBug(Bug bug);
}

View File

@ -142,7 +142,7 @@ template <bool pr> void IndexGenerator::AddFan(u32 numVerts)
if(pr)
{
for(; i<=numVerts-3; i+=3)
for(; i+3<=numVerts; i+=3)
{
*Tptr++ = index + i - 1;
*Tptr++ = index + i + 0;
@ -153,7 +153,7 @@ template <bool pr> void IndexGenerator::AddFan(u32 numVerts)
numT += 3;
}
for(; i<=numVerts-2; i+=2)
for(; i+2<=numVerts; i+=2)
{
*Tptr++ = index + i - 1;
*Tptr++ = index + i + 0;

View File

@ -6,6 +6,9 @@
#include <cmath>
#include <assert.h>
#include <locale.h>
#ifdef __APPLE__
#include <xlocale.h>
#endif
#include "LightingShaderGen.h"
#include "PixelShaderGen.h"
@ -213,6 +216,17 @@ static char swapModeTable[4][5];
static char text[16384];
// We can't use function defines since the Qualcomm shader compiler doesn't support it
static const char *GLSLConvertFunctions[] =
{
"frac", // HLSL
"fract", // GLSL
"lerp",
"mix"
};
#define FUNC_FRAC 0
#define FUNC_LERP 2
static void BuildSwapModeTable()
{
static const char *swapColors = "rgba";
@ -229,7 +243,7 @@ static void BuildSwapModeTable()
template<class T> static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType, RegisterState RegisterStates[4]);
template<class T> static void SampleTexture(T& out, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType);
template<class T> static void WriteAlphaTest(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth);
template<class T> static void WriteFog(T& out, pixel_shader_uid_data& uid_data);
template<class T> static void WriteFog(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType);
template<class T>
static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components)
@ -240,15 +254,23 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
? out.template GetUidData<pixel_shader_uid_data>() : dummy_data;
out.SetBuffer(text);
#ifndef ANDROID
locale_t locale;
locale_t old_locale;
if (out.GetBuffer() != NULL)
setlocale(LC_NUMERIC, "C"); // Reset locale for compilation
{
locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation
old_locale = uselocale(locale); // Apply the locale for this thread
}
#endif
text[sizeof(text) - 1] = 0x7C; // canary
unsigned int numStages = bpmem.genMode.numtevstages + 1;
unsigned int numTexgen = bpmem.genMode.numtexgens;
bool per_pixel_depth = bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable;
bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) || !g_ActiveConfig.bFastDepthCalc;
const bool bOpenGL = ApiType == API_OPENGL;
out.Write("//Pixel Shader for TEV stages\n");
out.Write("//%i TEV stages, %i texgens, %i IND stages\n",
@ -267,7 +289,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
out.Write("{\n");
out.Write("\tfloat z = fract( abs( x / y) ) * abs( y );\n");
out.Write("\treturn (x < 0) ? -z : z;\n");
out.Write("}\n\n");
out.Write("}\n");
// Declare samplers
for (int i = 0; i < 8; ++i)
@ -544,7 +566,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
}
// emulation of unsigned 8 overflow when casting if needed
if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
out.Write("\tprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
out.Write("\tprev = %s(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]);
AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult();
uid_data.Pretest = Pretest;
@ -552,23 +574,29 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
WriteAlphaTest<T>(out, uid_data, ApiType, dstAlphaMode, per_pixel_depth);
// the screen space depth value = far z + (clip z / clip w) * z range
if(ApiType == API_OPENGL || ApiType == API_D3D11)
// D3D9 doesn't support readback of depth in pixel shader, so we always have to calculate it again.
// This shouldn't be a performance issue as the written depth is usually still from perspective division
// but this isn't true for z-textures, so there will be depth issues between enabled and disabled z-textures fragments
if ((ApiType == API_OPENGL || ApiType == API_D3D11) && g_ActiveConfig.bFastDepthCalc)
out.Write("float zCoord = rawpos.z;\n");
else
{
out.SetConstantsUsed(C_ZBIAS+1, C_ZBIAS+1);
// dx9 doesn't support 4 component position, so we have to calculate it again
// the screen space depth value = far z + (clip z / clip w) * z range
out.Write("float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n");
}
// Note: depth textures are disabled if early depth test is enabled
// depth texture can safely be ignored if the result won't be written to the depth buffer (early_ztest) and isn't used for fog either
bool skip_ztexture = !per_pixel_depth && !bpmem.fog.c_proj_fsel.fsel;
uid_data.ztex_op = bpmem.ztex2.op;
uid_data.per_pixel_depth = per_pixel_depth;
uid_data.fog_fsel = bpmem.fog.c_proj_fsel.fsel;
// depth texture can safely be ignored if the result won't be written to the depth buffer (early_ztest) and isn't used for fog either
bool skip_ztexture = !per_pixel_depth && !bpmem.fog.c_proj_fsel.fsel;
// Note: z-textures are not written to depth buffer if early depth test is used
if (per_pixel_depth && bpmem.zcontrol.early_ztest)
out.Write("depth = zCoord;\n");
if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !skip_ztexture)
{
// use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format...
@ -578,7 +606,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
// U24 overflow emulation
out.Write("zCoord = zCoord * (16777215.0f/16777216.0f);\n");
out.Write("zCoord = frac(zCoord);\n");
out.Write("zCoord = %s(zCoord);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]);
out.Write("zCoord = zCoord * (16777216.0f/16777215.0f);\n");
// Note: depth texture output is only written to depth buffer if late depth test is used
@ -586,6 +614,8 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
if (per_pixel_depth)
out.Write("depth = zCoord;\n");
}
else if (per_pixel_depth && !bpmem.zcontrol.early_ztest)
out.Write("depth = zCoord;\n");
if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
{
@ -594,7 +624,7 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
}
else
{
WriteFog<T>(out, uid_data);
WriteFog<T>(out, uid_data, ApiType);
out.Write("\tocol0 = prev;\n");
}
@ -622,8 +652,13 @@ static void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE Api
if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("PixelShader generator - buffer too small, canary has been eaten!");
#ifndef ANDROID
if (out.GetBuffer() != NULL)
setlocale(LC_NUMERIC, ""); // restore locale
{
uselocale(old_locale); // restore locale
freelocale(locale);
}
#endif
}
@ -668,17 +703,15 @@ static const char *TEVCMPAlphaOPTable[16] =
" %s.a + (abs(dot(%s.rgb, comp24) - dot(%s.rgb, comp24)) < (0.5f/255.0f) ? %s.a : 0.0f)",//#define TEVCMP_BGR24_EQ 13
" %s.a + ((%s.a >= (%s.a + (0.25f/255.0f))) ? %s.a : 0.0f)",//#define TEVCMP_A8_GT 14
" %s.a + (abs(%s.a - %s.a) < (0.5f/255.0f) ? %s.a : 0.0f)"//#define TEVCMP_A8_EQ 15
};
template<class T>
static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE ApiType, RegisterState RegisterStates[4])
{
int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1);
bool bHasTexCoord = (u32)texcoord < bpmem.genMode.numtexgens;
bool bHasIndStage = bpmem.tevind[n].IsActive() && bpmem.tevind[n].bt < bpmem.genMode.numindstages;
bool bOpenGL = ApiType == API_OPENGL;
// HACK to handle cases where the tex gen is not enabled
if (!bHasTexCoord)
texcoord = 0;
@ -813,7 +846,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap];
out.Write("rastemp = %s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap);
out.Write("crastemp = frac(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
out.Write("crastemp = %s(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]);
}
@ -855,7 +888,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
out.Write("konsttemp = float4(%s, %s);\n", tevKSelTableC[kc], tevKSelTableA[ka]);
if(kc > 7 || ka > 7)
{
out.Write("ckonsttemp = frac(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
out.Write("ckonsttemp = %s(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]);
}
else
{
@ -874,7 +907,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
{
if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
{
out.Write("cprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
out.Write("cprev = %s(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]);
RegisterStates[0].AlphaNeedOverflowControl = false;
RegisterStates[0].ColorNeedOverflowControl = false;
}
@ -893,7 +926,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
out.SetConstantsUsed(C_COLORS+1,C_COLORS+1);
if(RegisterStates[1].AlphaNeedOverflowControl || RegisterStates[1].ColorNeedOverflowControl)
{
out.Write("cc0 = frac(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
out.Write("cc0 = %s(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]);
RegisterStates[1].AlphaNeedOverflowControl = false;
RegisterStates[1].ColorNeedOverflowControl = false;
}
@ -912,7 +945,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
out.SetConstantsUsed(C_COLORS+2,C_COLORS+2);
if(RegisterStates[2].AlphaNeedOverflowControl || RegisterStates[2].ColorNeedOverflowControl)
{
out.Write("cc1 = frac(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
out.Write("cc1 = frac(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]);
RegisterStates[2].AlphaNeedOverflowControl = false;
RegisterStates[2].ColorNeedOverflowControl = false;
}
@ -931,7 +964,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
out.SetConstantsUsed(C_COLORS+3,C_COLORS+3);
if(RegisterStates[3].AlphaNeedOverflowControl || RegisterStates[3].ColorNeedOverflowControl)
{
out.Write("cc2 = frac(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
out.Write("cc2 = %s(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]);
RegisterStates[3].AlphaNeedOverflowControl = false;
RegisterStates[3].ColorNeedOverflowControl = false;
}
@ -962,7 +995,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
out.Write("// color combine\n");
if (cc.clamp)
out.Write("%s = saturate(", tevCOutputTable[cc.dest]);
out.Write("%s = clamp(", tevCOutputTable[cc.dest]);
else
out.Write("%s = ", tevCOutputTable[cc.dest]);
@ -987,7 +1020,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
else if (cc.b == TEVCOLORARG_ZERO)
out.Write("%s*(float3(1.0f, 1.0f, 1.0f)-%s)", tevCInputTable[cc.a + 16], tevCInputTable[cc.c + 16]);
else
out.Write("lerp(%s, %s, %s)", tevCInputTable[cc.a + 16], tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]);
out.Write("%s(%s, %s, %s)", GLSLConvertFunctions[FUNC_LERP + bOpenGL], tevCInputTable[cc.a + 16], tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]);
out.Write("%s", tevBiasTable[cc.bias]);
@ -1004,7 +1037,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
tevCInputTable[cc.c + 16]);
}
if (cc.clamp)
out.Write(")");
out.Write(", 0.0, 1.0)");
out.Write(";\n");
RegisterStates[ac.dest].AlphaNeedOverflowControl = (ac.clamp == 0);
@ -1012,7 +1045,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
out.Write("// alpha combine\n");
if (ac.clamp)
out.Write("%s = saturate(", tevAOutputTable[ac.dest]);
out.Write("%s = clamp(", tevAOutputTable[ac.dest]);
else
out.Write("%s = ", tevAOutputTable[ac.dest]);
@ -1034,7 +1067,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
else if (ac.b == TEVALPHAARG_ZERO)
out.Write("%s.a*(1.0f-%s.a)", tevAInputTable[ac.a + 8], tevAInputTable[ac.c + 8]);
else
out.Write("lerp(%s.a, %s.a, %s.a)", tevAInputTable[ac.a + 8], tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]);
out.Write("%s(%s.a, %s.a, %s.a)", GLSLConvertFunctions[FUNC_LERP + bOpenGL], tevAInputTable[ac.a + 8], tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]);
out.Write("%s",tevBiasTable[ac.bias]);
@ -1053,7 +1086,7 @@ static void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, API_TYPE
tevAInputTable[ac.c + 8]);
}
if (ac.clamp)
out.Write(")");
out.Write(", 0.0, 1.0)");
out.Write(";\n\n");
out.Write("// TEV done\n");
}
@ -1157,8 +1190,10 @@ static const char *tevFogFuncsTable[] =
};
template<class T>
static void WriteFog(T& out, pixel_shader_uid_data& uid_data)
static void WriteFog(T& out, pixel_shader_uid_data& uid_data, API_TYPE ApiType)
{
bool bOpenGL = ApiType == API_OPENGL;
uid_data.fog_fsel = bpmem.fog.c_proj_fsel.fsel;
if(bpmem.fog.c_proj_fsel.fsel == 0)
return; // no Fog
@ -1191,7 +1226,7 @@ static void WriteFog(T& out, pixel_shader_uid_data& uid_data)
out.Write("\tze *= x_adjust;\n");
}
out.Write("\tfloat fog = saturate(ze - " I_FOG"[1].z);\n");
out.Write("\tfloat fog = clamp(ze - " I_FOG"[1].z, 0.0, 1.0);\n");
if (bpmem.fog.c_proj_fsel.fsel > 3)
{
@ -1203,7 +1238,7 @@ static void WriteFog(T& out, pixel_shader_uid_data& uid_data)
WARN_LOG(VIDEO, "Unknown Fog Type! %08x", bpmem.fog.c_proj_fsel.fsel);
}
out.Write("\tprev.rgb = lerp(prev.rgb, " I_FOG"[0].rgb, fog);\n");
out.Write("\tprev.rgb = %s(prev.rgb, " I_FOG"[0].rgb, fog);\n", GLSLConvertFunctions[FUNC_LERP + bOpenGL]);
}
void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components)

View File

@ -55,6 +55,9 @@ char *Statistics::ToString(char *ptr)
ptr+=sprintf(ptr,"CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
ptr+=sprintf(ptr,"BP loads: %i\n",stats.thisFrame.numBPLoads);
ptr+=sprintf(ptr,"BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
ptr+=sprintf(ptr,"Vertex streamed: %i kB\n",stats.thisFrame.bytesVertexStreamed/1024);
ptr+=sprintf(ptr,"Index streamed: %i kB\n",stats.thisFrame.bytesIndexStreamed/1024);
ptr+=sprintf(ptr,"Uniform streamed: %i kB\n",stats.thisFrame.bytesUniformStreamed/1024);
ptr+=sprintf(ptr,"Vertex Loaders: %i\n",stats.numVertexLoaders);
std::string text1;

View File

@ -60,6 +60,10 @@ struct Statistics
int numBufferSplits;
int numDListsCalled;
int bytesVertexStreamed;
int bytesIndexStreamed;
int bytesUniformStreamed;
};
ThisFrame thisFrame;
void ResetFrame();

View File

@ -32,6 +32,7 @@ TextureCache::TexCache TextureCache::textures;
TextureCache::BackupConfig TextureCache::backup_config;
bool invalidate_texture_cache_requested;
TextureCache::TCacheEntryBase::~TCacheEntryBase()
{
@ -49,6 +50,13 @@ TextureCache::TextureCache()
HiresTextures::Init(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str());
SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures);
invalidate_texture_cache_requested = false;
}
void TextureCache::RequestInvalidateTextureCache()
{
invalidate_texture_cache_requested = true;
}
void TextureCache::Invalidate()
@ -80,7 +88,8 @@ void TextureCache::OnConfigChanged(VideoConfig& config)
if (config.iSafeTextureCache_ColorSamples != backup_config.s_colorsamples ||
config.bTexFmtOverlayEnable != backup_config.s_texfmt_overlay ||
config.bTexFmtOverlayCenter != backup_config.s_texfmt_overlay_center ||
config.bHiresTextures != backup_config.s_hires_textures)
config.bHiresTextures != backup_config.s_hires_textures ||
invalidate_texture_cache_requested)
{
g_texture_cache->Invalidate();
@ -89,6 +98,8 @@ void TextureCache::OnConfigChanged(VideoConfig& config)
SetHash64Function(g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures);
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter);
invalidate_texture_cache_requested = false;
}
// TODO: Probably shouldn't clear all render targets here, just mark them dirty or something.

View File

@ -107,6 +107,8 @@ public:
static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, unsigned int srcFormat,
const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf);
static void RequestInvalidateTextureCache();
protected:
TextureCache();
@ -118,7 +120,6 @@ private:
static PC_TexFormat LoadCustomTexture(u64 tex_hash, int texformat, unsigned int level, unsigned int& width, unsigned int& height);
static void DumpTexture(TCacheEntryBase* entry, unsigned int level);
typedef std::map<u32, TCacheEntryBase*> TexCache;
static TexCache textures;

View File

@ -6,6 +6,9 @@
#include <stdio.h>
#include <math.h>
#include <locale.h>
#ifdef __APPLE__
#include <xlocale.h>
#endif
#include "TextureConversionShader.h"
#include "TextureDecoder.h"
@ -804,7 +807,10 @@ void WriteZ24Encoder(char* p, API_TYPE ApiType)
const char *GenerateEncodingShader(u32 format,API_TYPE ApiType)
{
setlocale(LC_NUMERIC, "C"); // Reset locale for compilation
#ifndef ANDROID
locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation
locale_t old_locale = uselocale(locale); // Apply the locale for this thread
#endif
text[sizeof(text) - 1] = 0x7C; // canary
char *p = text;
@ -887,8 +893,11 @@ const char *GenerateEncodingShader(u32 format,API_TYPE ApiType)
if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("TextureConversionShader generator - buffer too small, canary has been eaten!");
setlocale(LC_NUMERIC, ""); // restore locale
#ifndef ANDROID
uselocale(old_locale); // restore locale
freelocale(locale);
#endif
return text;
}

View File

@ -4,11 +4,15 @@
#include <math.h>
#include <locale.h>
#ifdef __APPLE__
#include <xlocale.h>
#endif
#include "NativeVertexFormat.h"
#include "BPMemory.h"
#include "CPMemory.h"
#include "DriverDetails.h"
#include "LightingShaderGen.h"
#include "VertexShaderGen.h"
#include "VideoConfig.h"
@ -71,9 +75,15 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type)
? out.template GetUidData<vertex_shader_uid_data>() : dummy_data;
out.SetBuffer(text);
#ifndef ANDROID
locale_t locale;
locale_t old_locale;
if (out.GetBuffer() != NULL)
setlocale(LC_NUMERIC, "C"); // Reset locale for compilation
{
locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation
old_locale = uselocale(locale); // Apply the locale for this thread
}
#endif
text[sizeof(text) - 1] = 0x7C; // canary
_assert_(bpmem.genMode.numtexgens == xfregs.numTexGen.numTexGens);
@ -214,13 +224,22 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type)
out.Write("int posmtx = int(fposmtx);\n");
}
out.Write("float4 pos = float4(dot(" I_TRANSFORMMATRICES"[posmtx], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+1], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+2], rawpos), 1);\n");
if (components & VB_HAS_NRMALL) {
out.Write("int normidx = posmtx >= 32 ? (posmtx-32) : posmtx;\n");
out.Write("float3 N0 = " I_NORMALMATRICES"[normidx].xyz, N1 = " I_NORMALMATRICES"[normidx+1].xyz, N2 = " I_NORMALMATRICES"[normidx+2].xyz;\n");
if (DriverDetails::HasBug(DriverDetails::BUG_NODYNUBOACCESS))
{
// This'll cause issues, but it can't be helped
out.Write("float4 pos = float4(dot(" I_TRANSFORMMATRICES"[0], rawpos), dot(" I_TRANSFORMMATRICES"[1], rawpos), dot(" I_TRANSFORMMATRICES"[2], rawpos), 1);\n");
if (components & VB_HAS_NRMALL)
out.Write("float3 N0 = " I_NORMALMATRICES"[0].xyz, N1 = " I_NORMALMATRICES"[1].xyz, N2 = " I_NORMALMATRICES"[2].xyz;\n");
}
else
{
out.Write("float4 pos = float4(dot(" I_TRANSFORMMATRICES"[posmtx], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+1], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+2], rawpos), 1);\n");
if (components & VB_HAS_NRMALL) {
out.Write("int normidx = posmtx >= 32 ? (posmtx-32) : posmtx;\n");
out.Write("float3 N0 = " I_NORMALMATRICES"[normidx].xyz, N1 = " I_NORMALMATRICES"[normidx+1].xyz, N2 = " I_NORMALMATRICES"[normidx+2].xyz;\n");
}
}
if (components & VB_HAS_NRM0)
out.Write("float3 _norm0 = normalize(float3(dot(N0, rawnorm0), dot(N1, rawnorm0), dot(N2, rawnorm0)));\n");
if (components & VB_HAS_NRM1)
@ -531,8 +550,13 @@ static void GenerateVertexShader(T& out, u32 components, API_TYPE api_type)
if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("VertexShader generator - buffer too small, canary has been eaten!");
#ifndef ANDROID
if (out.GetBuffer() != NULL)
setlocale(LC_NUMERIC, ""); // restore locale
{
uselocale(old_locale); // restore locale
freelocale(locale);
}
#endif
}
void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type)

View File

@ -10,12 +10,15 @@
#include "VideoCommon.h"
#include "FileUtil.h"
#include "Core.h"
#include "Movie.h"
VideoConfig g_Config;
VideoConfig g_ActiveConfig;
void UpdateActiveConfig()
{
if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
Movie::SetGraphicsConfig();
g_ActiveConfig = g_Config;
}
@ -64,6 +67,7 @@ void VideoConfig::Load(const char *ini_file)
iniFile.Get("Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle, 0);
iniFile.Get("Settings", "EnablePixelLighting", &bEnablePixelLighting, 0);
iniFile.Get("Settings", "HackedBufferUpload", &bHackedBufferUpload, 0);
iniFile.Get("Settings", "FastDepthCalc", &bFastDepthCalc, true);
iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0);
iniFile.Get("Settings", "EFBScale", &iEFBScale, (int) SCALE_1X); // native
@ -123,6 +127,7 @@ void VideoConfig::GameIniLoad(const char *ini_file)
iniFile.GetIfExists("Video_Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle);
iniFile.GetIfExists("Video_Settings", "EnablePixelLighting", &bEnablePixelLighting);
iniFile.GetIfExists("Video_Settings", "HackedBufferUpload", &bHackedBufferUpload);
iniFile.GetIfExists("Video_Settings", "FastDepthCalc", &bFastDepthCalc);
iniFile.GetIfExists("Video_Settings", "MSAA", &iMultisampleMode);
int tmp = -9000;
iniFile.GetIfExists("Video_Settings", "EFBScale", &tmp); // integral
@ -219,6 +224,7 @@ void VideoConfig::Save(const char *ini_file)
iniFile.Set("Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle);
iniFile.Set("Settings", "EnablePixelLighting", bEnablePixelLighting);
iniFile.Set("Settings", "HackedBufferUpload", bHackedBufferUpload);
iniFile.Set("Settings", "FastDepthCalc", bFastDepthCalc);
iniFile.Set("Settings", "ShowEFBCopyRegions", bShowEFBCopyRegions);
iniFile.Set("Settings", "MSAA", iMultisampleMode);
@ -283,6 +289,7 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini)
SET_IF_DIFFERS("Video_Settings", "AnaglyphStereoSeparation", iAnaglyphStereoSeparation);
SET_IF_DIFFERS("Video_Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle);
SET_IF_DIFFERS("Video_Settings", "EnablePixelLighting", bEnablePixelLighting);
SET_IF_DIFFERS("Video_Settings", "FastDepthCalc", bFastDepthCalc);
SET_IF_DIFFERS("Video_Settings", "MSAA", iMultisampleMode);
SET_IF_DIFFERS("Video_Settings", "EFBScale", iEFBScale); // integral
SET_IF_DIFFERS("Video_Settings", "DstAlphaPass", bDstAlphaPass);

View File

@ -123,6 +123,7 @@ struct VideoConfig
bool bUseBBox;
bool bEnablePixelLighting;
bool bHackedBufferUpload;
bool bFastDepthCalc;
int iLog; // CONF_ bits
int iSaveTargetId; // TODO: Should be dropped

View File

@ -182,6 +182,7 @@
<ClCompile Include="Src\CommandProcessor.cpp" />
<ClCompile Include="Src\CPMemory.cpp" />
<ClCompile Include="Src\Debugger.cpp" />
<ClCompile Include="Src\DriverDetails.cpp" />
<ClCompile Include="Src\EmuWindow.cpp" />
<ClCompile Include="Src\Fifo.cpp" />
<ClCompile Include="Src\FPSCounter.cpp" />
@ -229,6 +230,7 @@
<ClInclude Include="Src\CPMemory.h" />
<ClInclude Include="Src\DataReader.h" />
<ClInclude Include="Src\Debugger.h" />
<ClInclude Include="Src\DriverDetails.h" />
<ClInclude Include="Src\DLCache.h" />
<ClInclude Include="Src\EmuWindow.h" />
<ClInclude Include="Src\Fifo.h" />
@ -303,4 +305,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>