mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
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:
@ -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
|
||||
|
@ -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:
|
||||
|
69
Source/Core/VideoCommon/Src/DriverDetails.cpp
Normal file
69
Source/Core/VideoCommon/Src/DriverDetails.cpp
Normal 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;
|
||||
}
|
||||
}
|
52
Source/Core/VideoCommon/Src/DriverDetails.h
Normal file
52
Source/Core/VideoCommon/Src/DriverDetails.h
Normal 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);
|
||||
}
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -60,6 +60,10 @@ struct Statistics
|
||||
int numBufferSplits;
|
||||
|
||||
int numDListsCalled;
|
||||
|
||||
int bytesVertexStreamed;
|
||||
int bytesIndexStreamed;
|
||||
int bytesUniformStreamed;
|
||||
};
|
||||
ThisFrame thisFrame;
|
||||
void ResetFrame();
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -123,6 +123,7 @@ struct VideoConfig
|
||||
bool bUseBBox;
|
||||
bool bEnablePixelLighting;
|
||||
bool bHackedBufferUpload;
|
||||
bool bFastDepthCalc;
|
||||
|
||||
int iLog; // CONF_ bits
|
||||
int iSaveTargetId; // TODO: Should be dropped
|
||||
|
@ -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>
|
||||
|
Reference in New Issue
Block a user