diff options
| author | NeoBrainX <NeoBrainX@gmail.com> | 2013-06-17 12:05:47 +0200 |
|---|---|---|
| committer | NeoBrainX <NeoBrainX@gmail.com> | 2013-06-17 12:05:47 +0200 |
| commit | ca22872daed7c384db350b2987b21ea92299a9e8 (patch) | |
| tree | 21414cf12a5eb7a2b3cc4e0b1702aabf4c7c8890 /Source/Core/VideoCommon | |
| parent | f0ea525d3b4dea15363674c822943ecf38da26b3 (diff) | |
| parent | 43a4d418896f47ea971ccd83d5630a97f0f0000b (diff) | |
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
Diffstat (limited to 'Source/Core/VideoCommon')
| -rw-r--r-- | Source/Core/VideoCommon/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/BPMemory.cpp | 28 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/DriverDetails.cpp | 69 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/DriverDetails.h | 52 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/IndexGenerator.cpp | 4 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 99 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/Statistics.cpp | 3 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/Statistics.h | 4 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 13 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/TextureCacheBase.h | 3 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/TextureConversionShader.cpp | 15 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/VertexShaderGen.cpp | 40 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/VideoConfig.cpp | 7 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/VideoConfig.h | 1 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VideoCommon.vcxproj | 4 |
15 files changed, 295 insertions, 48 deletions
diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index 89b6828281..1bbc69a150 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -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 diff --git a/Source/Core/VideoCommon/Src/BPMemory.cpp b/Source/Core/VideoCommon/Src/BPMemory.cpp index e917632e1f..77f2f6bab3 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.cpp +++ b/Source/Core/VideoCommon/Src/BPMemory.cpp @@ -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: diff --git a/Source/Core/VideoCommon/Src/DriverDetails.cpp b/Source/Core/VideoCommon/Src/DriverDetails.cpp new file mode 100644 index 0000000000..8d3c2d9cf7 --- /dev/null +++ b/Source/Core/VideoCommon/Src/DriverDetails.cpp @@ -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; + } +} diff --git a/Source/Core/VideoCommon/Src/DriverDetails.h b/Source/Core/VideoCommon/Src/DriverDetails.h new file mode 100644 index 0000000000..524825f10b --- /dev/null +++ b/Source/Core/VideoCommon/Src/DriverDetails.h @@ -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); +} diff --git a/Source/Core/VideoCommon/Src/IndexGenerator.cpp b/Source/Core/VideoCommon/Src/IndexGenerator.cpp index 15b2311f89..3970d8c82f 100644 --- a/Source/Core/VideoCommon/Src/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/Src/IndexGenerator.cpp @@ -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; diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 2aa2468eef..9b8f3a9426 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -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) diff --git a/Source/Core/VideoCommon/Src/Statistics.cpp b/Source/Core/VideoCommon/Src/Statistics.cpp index 3dcd281b7f..0c69499355 100644 --- a/Source/Core/VideoCommon/Src/Statistics.cpp +++ b/Source/Core/VideoCommon/Src/Statistics.cpp @@ -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; diff --git a/Source/Core/VideoCommon/Src/Statistics.h b/Source/Core/VideoCommon/Src/Statistics.h index cb8a3afdc5..a7976651a5 100644 --- a/Source/Core/VideoCommon/Src/Statistics.h +++ b/Source/Core/VideoCommon/Src/Statistics.h @@ -60,6 +60,10 @@ struct Statistics int numBufferSplits; int numDListsCalled; + + int bytesVertexStreamed; + int bytesIndexStreamed; + int bytesUniformStreamed; }; ThisFrame thisFrame; void ResetFrame(); diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index d5d21f89d0..7d5b9354ad 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -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. diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.h b/Source/Core/VideoCommon/Src/TextureCacheBase.h index acfb2e94b2..1afcb8cd2d 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.h +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.h @@ -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; diff --git a/Source/Core/VideoCommon/Src/TextureConversionShader.cpp b/Source/Core/VideoCommon/Src/TextureConversionShader.cpp index 539d8799f9..40873b903e 100644 --- a/Source/Core/VideoCommon/Src/TextureConversionShader.cpp +++ b/Source/Core/VideoCommon/Src/TextureConversionShader.cpp @@ -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; } diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 6cbf273097..3edb51c505 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -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) diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 0b70b5440f..7827c0008a 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -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); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 9b5076df8c..ec4ad3ed3d 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -123,6 +123,7 @@ struct VideoConfig bool bUseBBox; bool bEnablePixelLighting; bool bHackedBufferUpload; + bool bFastDepthCalc; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj b/Source/Core/VideoCommon/VideoCommon.vcxproj index 1baf417797..617e4ec567 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj @@ -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>
\ No newline at end of file +</Project> |
