mirror of
https://github.com/blawar/GLideN64.git
synced 2024-06-30 08:24:05 +00:00
Add a new "fast" shader path that doesn't use texelFetch in glsl
This commit is contained in:
parent
466401cd02
commit
3d5a39e647
|
@ -309,8 +309,14 @@ copy /Y "$(OutDir)$(TargetName).*" "$(Mupen64PluginsDir_x64)")</Command>
|
|||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLFunctions.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerInputs.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilder.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderCommon.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderAccurate.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderFast.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramImpl.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactory.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryCommon.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryAccurate.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryFast.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_FXAA.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_ShaderStorage.cpp" />
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_SpecialShadersFactory.cpp" />
|
||||
|
@ -465,8 +471,14 @@ copy /Y "$(OutDir)$(TargetName).*" "$(Mupen64PluginsDir_x64)")</Command>
|
|||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLFunctions.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerInputs.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilder.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderCommon.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderAccurate.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderFast.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramImpl.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactory.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryCommon.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryAccurate.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryFast.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_FXAA.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_ShaderPart.h" />
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_ShaderStorage.h" />
|
||||
|
|
|
@ -221,6 +221,9 @@
|
|||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilder.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderCommon.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramImpl.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
|
@ -236,6 +239,9 @@
|
|||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactory.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryCommon.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerInputs.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
|
@ -425,6 +431,18 @@
|
|||
<ClCompile Include="..\..\src\BufferCopy\BlueNoiseTexture.cpp">
|
||||
<Filter>Source Files\BufferCopy</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderAccurate.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderFast.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryAccurate.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryFast.cpp">
|
||||
<Filter>Source Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\3DMath.h">
|
||||
|
@ -787,6 +805,24 @@
|
|||
<ClInclude Include="..\..\src\resource.h">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderCommon.h">
|
||||
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderAccurate.h">
|
||||
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramBuilderFast.h">
|
||||
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryCommon.h">
|
||||
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryAccurate.h">
|
||||
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Graphics\OpenGLContext\GLSL\glsl_CombinerProgramUniformFactoryFast.h">
|
||||
<Filter>Header Files\Graphics\OpenGL\GLSL</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\src\GLideN64.rc">
|
||||
|
|
|
@ -89,8 +89,14 @@ set(GLideN64_SOURCES
|
|||
Graphics/OpenGLContext/opengl_Utils.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_CombinerInputs.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderAccurate.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderFast.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_CombinerProgramImpl.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactoryCommon.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactoryAccurate.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactoryFast.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_FXAA.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_ShaderStorage.cpp
|
||||
Graphics/OpenGLContext/GLSL/glsl_SpecialShadersFactory.cpp
|
||||
|
|
|
@ -51,6 +51,7 @@ void Config::resetToDefaults()
|
|||
generalEmulation.enableShadersStorage = 1;
|
||||
generalEmulation.enableLegacyBlending = 0;
|
||||
generalEmulation.enableHybridFilter = 1;
|
||||
generalEmulation.enableInaccurateTextureCoordinates = 0;
|
||||
generalEmulation.hacks = 0;
|
||||
#if defined(OS_ANDROID) || defined(OS_IOS)
|
||||
generalEmulation.enableFragmentDepthWrite = 0;
|
||||
|
|
|
@ -65,6 +65,7 @@ struct Config
|
|||
u32 enableShadersStorage;
|
||||
u32 enableLegacyBlending;
|
||||
u32 enableHybridFilter;
|
||||
u32 enableInaccurateTextureCoordinates;
|
||||
u32 enableFragmentDepthWrite;
|
||||
u32 hacks;
|
||||
#if defined(OS_ANDROID) || defined(OS_IOS)
|
||||
|
|
|
@ -223,6 +223,7 @@ void ConfigDialog::_init(bool reInit, bool blockCustomSettings)
|
|||
|
||||
// Emulation settings
|
||||
ui->emulateLodCheckBox->setChecked(config.generalEmulation.enableLOD != 0);
|
||||
ui->enableInaccurateTextureCoordinatesCheckBox->setChecked(config.generalEmulation.enableInaccurateTextureCoordinates != 0);
|
||||
ui->enableHWLightingCheckBox->setChecked(config.generalEmulation.enableHWLighting != 0);
|
||||
ui->enableCoverageCheckBox->setChecked(config.generalEmulation.enableCoverage != 0);
|
||||
ui->enableShadersStorageCheckBox->setChecked(config.generalEmulation.enableShadersStorage != 0);
|
||||
|
@ -562,6 +563,7 @@ void ConfigDialog::accept(bool justSave) {
|
|||
|
||||
// Emulation settings
|
||||
config.generalEmulation.enableLOD = ui->emulateLodCheckBox->isChecked() ? 1 : 0;
|
||||
config.generalEmulation.enableInaccurateTextureCoordinates = ui->enableInaccurateTextureCoordinatesCheckBox->isChecked() ? 1 : 0;
|
||||
config.generalEmulation.enableHWLighting = ui->enableHWLightingCheckBox->isChecked() ? 1 : 0;
|
||||
config.generalEmulation.enableCoverage = ui->enableCoverageCheckBox->isChecked() ? 1 : 0;
|
||||
config.generalEmulation.enableShadersStorage = ui->enableShadersStorageCheckBox->isChecked() ? 1 : 0;
|
||||
|
|
|
@ -48,6 +48,7 @@ void _loadSettings(QSettings & settings)
|
|||
config.generalEmulation.enableHiresNoiseDithering = settings.value("enableHiresNoiseDithering", config.generalEmulation.enableHiresNoiseDithering).toInt();
|
||||
config.generalEmulation.rdramImageDitheringMode = settings.value("rdramImageDitheringMode", config.generalEmulation.rdramImageDitheringMode).toInt();
|
||||
config.generalEmulation.enableLOD = settings.value("enableLOD", config.generalEmulation.enableLOD).toInt();
|
||||
config.generalEmulation.enableInaccurateTextureCoordinates = settings.value("enableFastInaccurateShaders", config.generalEmulation.enableInaccurateTextureCoordinates).toInt();
|
||||
config.generalEmulation.enableHWLighting = settings.value("enableHWLighting", config.generalEmulation.enableHWLighting).toInt();
|
||||
config.generalEmulation.enableCoverage = settings.value("enableCoverage", config.generalEmulation.enableCoverage).toInt();
|
||||
config.generalEmulation.enableShadersStorage = settings.value("enableShadersStorage", config.generalEmulation.enableShadersStorage).toInt();
|
||||
|
@ -193,6 +194,7 @@ void _writeSettingsToFile(const QString & filename)
|
|||
settings.setValue("enableHiresNoiseDithering", config.generalEmulation.enableHiresNoiseDithering);
|
||||
settings.setValue("rdramImageDitheringMode", config.generalEmulation.rdramImageDitheringMode);
|
||||
settings.setValue("enableLOD", config.generalEmulation.enableLOD);
|
||||
settings.setValue("enableFastInaccurateShaders", config.generalEmulation.enableInaccurateTextureCoordinates);
|
||||
settings.setValue("enableHWLighting", config.generalEmulation.enableHWLighting);
|
||||
settings.setValue("enableCoverage", config.generalEmulation.enableCoverage);
|
||||
settings.setValue("enableShadersStorage", config.generalEmulation.enableShadersStorage);
|
||||
|
@ -359,8 +361,8 @@ void resetSettings(const QString & _strIniFolder)
|
|||
static
|
||||
u32 Adler32(u32 crc, const void *buffer, u32 count)
|
||||
{
|
||||
register u32 s1 = crc & 0xFFFF;
|
||||
register u32 s2 = (crc >> 16) & 0xFFFF;
|
||||
u32 s1 = crc & 0xFFFF;
|
||||
u32 s2 = (crc >> 16) & 0xFFFF;
|
||||
int k;
|
||||
const u8 *Buffer = (const u8*)buffer;
|
||||
|
||||
|
@ -465,6 +467,7 @@ void saveCustomRomSettings(const QString & _strIniFolder, const char * _strRomNa
|
|||
WriteCustomSetting(generalEmulation, enableHiresNoiseDithering);
|
||||
WriteCustomSetting(generalEmulation, rdramImageDitheringMode);
|
||||
WriteCustomSetting(generalEmulation, enableLOD);
|
||||
WriteCustomSetting(generalEmulation, enableInaccurateTextureCoordinates);
|
||||
WriteCustomSetting(generalEmulation, enableHWLighting);
|
||||
WriteCustomSetting(generalEmulation, enableCoverage);
|
||||
WriteCustomSetting(generalEmulation, enableShadersStorage);
|
||||
|
@ -540,11 +543,11 @@ void saveCustomRomSettings(const QString & _strIniFolder, const char * _strRomNa
|
|||
|
||||
settings.beginGroup("hotkeys");
|
||||
for (u32 idx = 0; idx < Config::HotKey::hkTotal; ++idx) {
|
||||
if (origConfig.hotkeys.keys[idx] != config.hotkeys.keys[idx] ||
|
||||
if (origConfig.hotkeys.keys[idx] != config.hotkeys.keys[idx] ||
|
||||
origConfig.hotkeys.keys[idx] != settings.value(Config::hotkeyIniName(idx), config.hotkeys.keys[idx]).toInt()) {
|
||||
settings.setValue(Config::hotkeyIniName(idx), config.hotkeys.keys[idx]);
|
||||
}
|
||||
if (origConfig.hotkeys.enabledKeys[idx] != config.hotkeys.enabledKeys[idx] ||
|
||||
if (origConfig.hotkeys.enabledKeys[idx] != config.hotkeys.enabledKeys[idx] ||
|
||||
origConfig.hotkeys.enabledKeys[idx] != settings.value(Config::enabledHotkeyIniName(idx), config.hotkeys.enabledKeys[idx]).toInt()) {
|
||||
settings.setValue(Config::enabledHotkeyIniName(idx), config.hotkeys.enabledKeys[idx]);
|
||||
}
|
||||
|
|
|
@ -1098,6 +1098,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableInaccurateTextureCoordinatesCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-weight:600;">Enable inaccurate texture coordinates. </span></p><p>Enables inaccurate texture coordinate calculations. This can improve performance and texture pack compatibity at the cost of accuracy.</p><p>[Recommended: Unchecked, unless performance is hurt or for texture pack compatibility]</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable inaccurate texture coordinates</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableShadersStorageCheckBox">
|
||||
<property name="toolTip">
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace graphics {
|
|||
vecOptions.push_back(config.frameBufferEmulation.N64DepthCompare == Config::dcCompatible ? 1 : 0);
|
||||
vecOptions.push_back(config.generalEmulation.enableLegacyBlending);
|
||||
vecOptions.push_back(config.generalEmulation.enableFragmentDepthWrite);
|
||||
vecOptions.push_back(config.generalEmulation.enableInaccurateTextureCoordinates);
|
||||
u32 optionsSet = 0;
|
||||
for (u32 i = 0; i < vecOptions.size(); ++i)
|
||||
optionsSet |= vecOptions[i] << i;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,6 +2,8 @@
|
|||
#include <memory>
|
||||
#include <Combiner.h>
|
||||
#include <Graphics/OpenGLContext/opengl_GLInfo.h>
|
||||
#include "glsl_CombinerProgramUniformFactory.h"
|
||||
#include "glsl_ShaderPart.h"
|
||||
|
||||
namespace graphics {
|
||||
class CombinerProgram;
|
||||
|
@ -12,98 +14,121 @@ namespace opengl {
|
|||
}
|
||||
|
||||
namespace glsl {
|
||||
|
||||
class ShaderPart;
|
||||
class CombinerInputs;
|
||||
class CombinerProgramUniformFactory;
|
||||
}
|
||||
|
||||
class CombinerProgramBuilder
|
||||
{
|
||||
public:
|
||||
CombinerProgramBuilder(const opengl::GLInfo & _glinfo, opengl::CachedUseProgram * _useProgram);
|
||||
~CombinerProgramBuilder();
|
||||
namespace glsl {
|
||||
|
||||
graphics::CombinerProgram * buildCombinerProgram(Combiner & _color, Combiner & _alpha, const CombinerKey & _key);
|
||||
class TextureConvert {
|
||||
public:
|
||||
void setMode(u32 _mode) {
|
||||
m_mode = _mode;
|
||||
}
|
||||
|
||||
const ShaderPart * getVertexShaderHeader() const;
|
||||
bool getBilerp1() const {
|
||||
return (m_mode & 1) != 0;
|
||||
}
|
||||
|
||||
const ShaderPart * getFragmentShaderHeader() const;
|
||||
bool getBilerp0() const {
|
||||
return (m_mode & 2) != 0;
|
||||
}
|
||||
|
||||
const ShaderPart * getFragmentShaderEnd() const;
|
||||
bool useYUVCoversion() const {
|
||||
return (m_mode & 3) != 3;
|
||||
}
|
||||
|
||||
bool isObsolete() const;
|
||||
bool useTextureFiltering() const {
|
||||
return (m_mode & 3) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
CombinerInputs compileCombiner(const CombinerKey & _key, Combiner & _color, Combiner & _alpha, std::string & _strShader);
|
||||
private:
|
||||
u32 m_mode;
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<ShaderPart> ShaderPartPtr;
|
||||
ShaderPartPtr m_blender1;
|
||||
ShaderPartPtr m_blender2;
|
||||
ShaderPartPtr m_blenderAlpha;
|
||||
ShaderPartPtr m_legacyBlender;
|
||||
ShaderPartPtr m_clamp;
|
||||
ShaderPartPtr m_signExtendColorC;
|
||||
ShaderPartPtr m_signExtendAlphaC;
|
||||
ShaderPartPtr m_signExtendColorABD;
|
||||
ShaderPartPtr m_signExtendAlphaABD;
|
||||
ShaderPartPtr m_alphaTest;
|
||||
ShaderPartPtr m_callDither;
|
||||
class CombinerProgramBuilder
|
||||
{
|
||||
public:
|
||||
using ShaderPartPtr = std::unique_ptr<ShaderPart>;
|
||||
|
||||
ShaderPartPtr m_vertexHeader;
|
||||
ShaderPartPtr m_vertexEnd;
|
||||
ShaderPartPtr m_vertexRect;
|
||||
ShaderPartPtr m_vertexTexturedRect;
|
||||
ShaderPartPtr m_vertexTriangle;
|
||||
ShaderPartPtr m_vertexTexturedTriangle;
|
||||
CombinerProgramBuilder(const opengl::GLInfo & _glinfo, opengl::CachedUseProgram * _useProgram,
|
||||
std::unique_ptr<CombinerProgramUniformFactory> _uniformFactory);
|
||||
virtual ~CombinerProgramBuilder();
|
||||
|
||||
ShaderPartPtr m_fragmentHeader;
|
||||
ShaderPartPtr m_fragmentGlobalVariablesTex;
|
||||
ShaderPartPtr m_fragmentGlobalVariablesNotex;
|
||||
ShaderPartPtr m_fragmentHeaderNoise;
|
||||
ShaderPartPtr m_fragmentHeaderWriteDepth;
|
||||
ShaderPartPtr m_fragmentHeaderCalcLight;
|
||||
ShaderPartPtr m_fragmentHeaderMipMap;
|
||||
ShaderPartPtr m_fragmentHeaderTextureEngine;
|
||||
ShaderPartPtr m_fragmentHeaderReadMSTex;
|
||||
ShaderPartPtr m_fragmentHeaderDither;
|
||||
ShaderPartPtr m_fragmentHeaderDepthCompare;
|
||||
ShaderPartPtr m_fragmentHeaderReadTex;
|
||||
ShaderPartPtr m_fragmentHeaderReadTexCopyMode;
|
||||
ShaderPartPtr m_fragmentMain;
|
||||
ShaderPartPtr m_fragmentMain2Cycle;
|
||||
ShaderPartPtr m_fragmentBlendMux;
|
||||
ShaderPartPtr m_fragmentReadTex0;
|
||||
ShaderPartPtr m_fragmentReadTex1;
|
||||
ShaderPartPtr m_fragmentCorrectTexCoords;
|
||||
ShaderPartPtr m_fragmentTextureEngineTex0;
|
||||
ShaderPartPtr m_fragmentTextureEngineTex1;
|
||||
ShaderPartPtr m_fragmentReadTexCopyMode;
|
||||
ShaderPartPtr m_fragmentReadTexMipmap;
|
||||
ShaderPartPtr m_fragmentCallN64Depth;
|
||||
ShaderPartPtr m_fragmentRenderTarget;
|
||||
ShaderPartPtr m_shaderFragmentMainEnd;
|
||||
graphics::CombinerProgram * buildCombinerProgram(Combiner & _color, Combiner & _alpha, const CombinerKey & _key);
|
||||
|
||||
ShaderPartPtr m_shaderNoise;
|
||||
ShaderPartPtr m_shaderDither;
|
||||
ShaderPartPtr m_shaderWriteDepth;
|
||||
ShaderPartPtr m_shaderMipmap;
|
||||
ShaderPartPtr m_shaderCalcLight;
|
||||
ShaderPartPtr m_shaderReadtex;
|
||||
ShaderPartPtr m_shaderReadtexCopyMode;
|
||||
ShaderPartPtr m_shaderN64DepthCompare;
|
||||
ShaderPartPtr m_shaderN64DepthRender;
|
||||
ShaderPartPtr m_shaderTextureEngine;
|
||||
ShaderPartPtr m_shaderCoverage;
|
||||
virtual const ShaderPart * getVertexShaderHeader() const = 0;
|
||||
|
||||
std::unique_ptr<CombinerProgramUniformFactory> m_uniformFactory;
|
||||
virtual const ShaderPart * getFragmentShaderHeader() const = 0;
|
||||
|
||||
GLuint m_vertexShaderRect;
|
||||
GLuint m_vertexShaderTriangle;
|
||||
GLuint m_vertexShaderTexturedRect;
|
||||
GLuint m_vertexShaderTexturedTriangle;
|
||||
opengl::CachedUseProgram * m_useProgram;
|
||||
u32 m_combinerOptionsBits;
|
||||
bool m_useCoverage = false;
|
||||
};
|
||||
virtual const ShaderPart * getFragmentShaderEnd() const = 0;
|
||||
|
||||
virtual bool isObsolete() const = 0;
|
||||
|
||||
static u32 s_cycleType;
|
||||
static TextureConvert s_textureConvert;
|
||||
|
||||
private:
|
||||
CombinerInputs compileCombiner(const CombinerKey & _key, Combiner & _color, Combiner & _alpha, std::string & _strShader);
|
||||
|
||||
virtual void _writeSignExtendAlphaC(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeSignExtendAlphaABD(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeAlphaTest(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeSignExtendColorC(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeSignExtendColorABD(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeClamp(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeCallDither(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeBlender1(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeBlender2(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeBlenderAlpha(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeLegacyBlender(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeader(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentGlobalVariablesTex(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeaderDither(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeaderNoise(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeaderWriteDepth(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeaderDepthCompare(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeaderReadMSTex(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeaderClampWrapMirrorEngine(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeaderMipMap(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeaderReadTex(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeaderReadTexCopyMode(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentGlobalVariablesNotex(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentHeaderCalcLight(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentMain2Cycle(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentMain(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentBlendMux(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderCoverage(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentCorrectTexCoords(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentClampWrapMirrorEngineTex0(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentClampWrapMirrorEngineTex1(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentReadTexMipmap(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentReadTex0(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentReadTex1(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentReadTexCopyMode(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentCallN64Depth(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeFragmentRenderTarget(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderFragmentMainEnd(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderCalcLight(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderClampWrapMirrorEngine(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderMipmap(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderReadtex(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderReadtexCopyMode(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderNoise(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderDither(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderWriteDepth(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderN64DepthCompare(std::stringstream& ssShader) const = 0;
|
||||
virtual void _writeShaderN64DepthRender(std::stringstream& ssShader) const = 0;
|
||||
|
||||
virtual GLuint _getVertexShaderRect() const = 0;
|
||||
virtual GLuint _getVertexShaderTriangle() const = 0;
|
||||
virtual GLuint _getVertexShaderTexturedRect() const = 0;
|
||||
virtual GLuint _getVertexShaderTexturedTriangle() const = 0;
|
||||
|
||||
std::unique_ptr<CombinerProgramUniformFactory> m_uniformFactory;
|
||||
opengl::CachedUseProgram * m_useProgram;
|
||||
bool m_useCoverage = false;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
#include <Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.h>
|
||||
|
||||
namespace glsl {
|
||||
|
||||
class CombinerProgramUniformFactory;
|
||||
|
||||
class CombinerProgramBuilderAccurate : public glsl::CombinerProgramBuilderCommon
|
||||
{
|
||||
public:
|
||||
CombinerProgramBuilderAccurate(const opengl::GLInfo & _glinfo, opengl::CachedUseProgram * _useProgram);
|
||||
|
||||
private:
|
||||
void _writeFragmentGlobalVariablesTex(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderReadMSTex(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderReadTex(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderReadTexCopyMode(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderClampWrapMirrorEngine(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentClampWrapMirrorEngineTex0(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentClampWrapMirrorEngineTex1(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentReadTex0(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentReadTex1(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentReadTexCopyMode(std::stringstream& ssShader) const override;
|
||||
void _writeShaderClampWrapMirrorEngine(std::stringstream& ssShader) const override;
|
||||
void _writeShaderMipmap(std::stringstream& ssShader) const override;
|
||||
void _writeShaderReadtex(std::stringstream& ssShader) const override;
|
||||
void _writeShaderReadtexCopyMode(std::stringstream& ssShader) const override;
|
||||
|
||||
ShaderPartPtr m_fragmentGlobalVariablesTex;
|
||||
ShaderPartPtr m_fragmentHeaderTextureEngine;
|
||||
ShaderPartPtr m_fragmentHeaderReadMSTex;
|
||||
ShaderPartPtr m_fragmentHeaderReadTex;
|
||||
ShaderPartPtr m_fragmentHeaderReadTexCopyMode;
|
||||
ShaderPartPtr m_fragmentReadTexCopyMode;
|
||||
ShaderPartPtr m_fragmentReadTex0;
|
||||
ShaderPartPtr m_fragmentReadTex1;
|
||||
ShaderPartPtr m_shaderMipmap;
|
||||
ShaderPartPtr m_shaderReadtex;
|
||||
ShaderPartPtr m_shaderReadtexCopyMode;
|
||||
ShaderPartPtr m_shaderTextureEngine;
|
||||
ShaderPartPtr m_fragmentTextureEngineTex0;
|
||||
ShaderPartPtr m_fragmentTextureEngineTex1;
|
||||
};
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,118 @@
|
|||
#pragma once
|
||||
#include <Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.h>
|
||||
|
||||
namespace glsl {
|
||||
|
||||
class CombinerProgramUniformFactory;
|
||||
|
||||
class CombinerProgramBuilderCommon : public glsl::CombinerProgramBuilder
|
||||
{
|
||||
public:
|
||||
CombinerProgramBuilderCommon(const opengl::GLInfo & _glinfo, opengl::CachedUseProgram * _useProgram,
|
||||
std::unique_ptr<CombinerProgramUniformFactory> _uniformFactory,
|
||||
std::unique_ptr<ShaderPart> _vertexTexturedTriangle);
|
||||
~CombinerProgramBuilderCommon();
|
||||
|
||||
const ShaderPart * getVertexShaderHeader() const override;
|
||||
|
||||
const ShaderPart * getFragmentShaderHeader() const override;
|
||||
|
||||
const ShaderPart * getFragmentShaderEnd() const override;
|
||||
|
||||
bool isObsolete() const override;
|
||||
|
||||
private:
|
||||
|
||||
GLuint _getVertexShaderRect() const override;
|
||||
GLuint _getVertexShaderTriangle() const override;
|
||||
GLuint _getVertexShaderTexturedRect() const override;
|
||||
GLuint _getVertexShaderTexturedTriangle() const override;
|
||||
|
||||
void _writeSignExtendAlphaC(std::stringstream& ssShader) const override;
|
||||
void _writeSignExtendAlphaABD(std::stringstream& ssShader) const override;
|
||||
void _writeAlphaTest(std::stringstream& ssShader) const override;
|
||||
void _writeSignExtendColorC(std::stringstream& ssShader) const override;
|
||||
void _writeSignExtendColorABD(std::stringstream& ssShader) const override;
|
||||
void _writeClamp(std::stringstream& ssShader) const override;
|
||||
void _writeCallDither(std::stringstream& ssShader) const override;
|
||||
void _writeBlender1(std::stringstream& ssShader) const override;
|
||||
void _writeBlender2(std::stringstream& ssShader) const override;
|
||||
void _writeBlenderAlpha(std::stringstream& ssShader) const override;
|
||||
void _writeLegacyBlender(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeader(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderDither(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderNoise(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderWriteDepth(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderDepthCompare(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderMipMap(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentGlobalVariablesNotex(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderCalcLight(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentMain2Cycle(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentMain(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentBlendMux(std::stringstream& ssShader) const override;
|
||||
void _writeShaderCoverage(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentCorrectTexCoords(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentReadTexMipmap(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentCallN64Depth(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentRenderTarget(std::stringstream& ssShader) const override;
|
||||
void _writeShaderFragmentMainEnd(std::stringstream& ssShader) const override;
|
||||
void _writeShaderCalcLight(std::stringstream& ssShader) const override;
|
||||
void _writeShaderNoise(std::stringstream& ssShader) const override;
|
||||
void _writeShaderDither(std::stringstream& ssShader) const override;
|
||||
void _writeShaderWriteDepth(std::stringstream& ssShader) const override;
|
||||
void _writeShaderN64DepthCompare(std::stringstream& ssShader) const override;
|
||||
void _writeShaderN64DepthRender(std::stringstream& ssShader) const override;
|
||||
|
||||
ShaderPartPtr m_blender1;
|
||||
ShaderPartPtr m_blender2;
|
||||
ShaderPartPtr m_blenderAlpha;
|
||||
ShaderPartPtr m_legacyBlender;
|
||||
ShaderPartPtr m_clamp;
|
||||
ShaderPartPtr m_signExtendColorC;
|
||||
ShaderPartPtr m_signExtendAlphaC;
|
||||
ShaderPartPtr m_signExtendColorABD;
|
||||
ShaderPartPtr m_signExtendAlphaABD;
|
||||
ShaderPartPtr m_alphaTest;
|
||||
ShaderPartPtr m_callDither;
|
||||
|
||||
ShaderPartPtr m_vertexHeader;
|
||||
ShaderPartPtr m_vertexEnd;
|
||||
ShaderPartPtr m_vertexRect;
|
||||
ShaderPartPtr m_vertexTexturedRect;
|
||||
ShaderPartPtr m_vertexTriangle;
|
||||
|
||||
ShaderPartPtr m_fragmentHeader;
|
||||
ShaderPartPtr m_fragmentGlobalVariablesNotex;
|
||||
ShaderPartPtr m_fragmentHeaderNoise;
|
||||
ShaderPartPtr m_fragmentHeaderWriteDepth;
|
||||
ShaderPartPtr m_fragmentHeaderCalcLight;
|
||||
ShaderPartPtr m_fragmentHeaderMipMap;
|
||||
ShaderPartPtr m_fragmentHeaderDither;
|
||||
ShaderPartPtr m_fragmentHeaderDepthCompare;
|
||||
ShaderPartPtr m_fragmentMain;
|
||||
ShaderPartPtr m_fragmentMain2Cycle;
|
||||
ShaderPartPtr m_fragmentBlendMux;
|
||||
ShaderPartPtr m_fragmentCorrectTexCoords;
|
||||
ShaderPartPtr m_fragmentReadTexMipmap;
|
||||
ShaderPartPtr m_fragmentCallN64Depth;
|
||||
ShaderPartPtr m_fragmentRenderTarget;
|
||||
ShaderPartPtr m_shaderFragmentMainEnd;
|
||||
|
||||
ShaderPartPtr m_shaderNoise;
|
||||
ShaderPartPtr m_shaderDither;
|
||||
ShaderPartPtr m_shaderWriteDepth;
|
||||
ShaderPartPtr m_shaderCalcLight;
|
||||
ShaderPartPtr m_shaderN64DepthCompare;
|
||||
ShaderPartPtr m_shaderN64DepthRender;
|
||||
ShaderPartPtr m_shaderCoverage;
|
||||
|
||||
u32 m_combinerOptionsBits;
|
||||
|
||||
GLuint m_vertexShaderRect;
|
||||
GLuint m_vertexShaderTriangle;
|
||||
GLuint m_vertexShaderTexturedRect;
|
||||
GLuint m_vertexShaderTexturedTriangle;
|
||||
};
|
||||
|
||||
}
|
||||
|
1186
src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderFast.cpp
Normal file
1186
src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderFast.cpp
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
#include <Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.h>
|
||||
|
||||
namespace glsl {
|
||||
|
||||
class CombinerProgramUniformFactory;
|
||||
|
||||
class CombinerProgramBuilderFast : public glsl::CombinerProgramBuilderCommon
|
||||
{
|
||||
public:
|
||||
CombinerProgramBuilderFast(const opengl::GLInfo & _glinfo, opengl::CachedUseProgram * _useProgram);
|
||||
|
||||
private:
|
||||
|
||||
void _writeFragmentGlobalVariablesTex(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderReadMSTex(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderReadTex(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderReadTexCopyMode(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentHeaderClampWrapMirrorEngine(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentClampWrapMirrorEngineTex0(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentClampWrapMirrorEngineTex1(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentReadTex0(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentReadTex1(std::stringstream& ssShader) const override;
|
||||
void _writeFragmentReadTexCopyMode(std::stringstream& ssShader) const override;
|
||||
void _writeShaderClampWrapMirrorEngine(std::stringstream& ssShader) const override;
|
||||
void _writeShaderMipmap(std::stringstream& ssShader) const override;
|
||||
void _writeShaderReadtex(std::stringstream& ssShader) const override;
|
||||
void _writeShaderReadtexCopyMode(std::stringstream& ssShader) const override;
|
||||
|
||||
ShaderPartPtr m_fragmentGlobalVariablesTex;
|
||||
ShaderPartPtr m_fragmentHeaderClampWrapMirror;
|
||||
ShaderPartPtr m_fragmentHeaderReadMSTex;
|
||||
ShaderPartPtr m_fragmentHeaderReadTex;
|
||||
ShaderPartPtr m_fragmentHeaderReadTexCopyMode;
|
||||
ShaderPartPtr m_fragmentReadTex0;
|
||||
ShaderPartPtr m_fragmentReadTex1;
|
||||
ShaderPartPtr m_fragmentClampWrapMirrorTex0;
|
||||
ShaderPartPtr m_fragmentClampWrapMirrorTex1;
|
||||
ShaderPartPtr m_fragmentReadTexCopyMode;
|
||||
ShaderPartPtr m_shaderMipmap;
|
||||
ShaderPartPtr m_shaderReadtex;
|
||||
ShaderPartPtr m_shaderReadtexCopyMode;
|
||||
ShaderPartPtr m_shaderClampWrapMirror;
|
||||
};
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -4,18 +4,85 @@
|
|||
|
||||
namespace glsl {
|
||||
|
||||
class CombinerProgramUniformFactory
|
||||
{
|
||||
public:
|
||||
CombinerProgramUniformFactory(const opengl::GLInfo & _glInfo);
|
||||
class CombinerProgramUniformFactory {
|
||||
public:
|
||||
CombinerProgramUniformFactory(const opengl::GLInfo & _glInfo);
|
||||
virtual ~CombinerProgramUniformFactory();
|
||||
|
||||
void buildUniforms(GLuint _program,
|
||||
const CombinerInputs & _inputs,
|
||||
const CombinerKey & _key,
|
||||
UniformGroups & _uniforms);
|
||||
void buildUniforms(GLuint _program,
|
||||
const CombinerInputs &_inputs,
|
||||
const CombinerKey &_key,
|
||||
UniformGroups &_uniforms);
|
||||
|
||||
private:
|
||||
const opengl::GLInfo & m_glInfo;
|
||||
};
|
||||
private:
|
||||
virtual void _addNoiseTex(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addScreenSpaceTriangleInfo(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addRasterInfo(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addViewportInfo(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addDepthTex(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addDepthScale(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addTextures(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addMSAATextures(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addFrameBufferInfo(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addMipmap(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addMipmap2(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addTextureFetchMode(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addTexturePersp(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addTextureSize(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const = 0;
|
||||
|
||||
virtual void _addTextureParams(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const = 0;
|
||||
|
||||
virtual void _addClampWrapMirrorEngine(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const = 0;
|
||||
|
||||
virtual void _addFog(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addBlendMode1Cycle(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addBlendMode2Cycle(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addBlendCvg(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addDitherMode(GLuint _program, UniformGroups &_uniforms, bool _usesNoise) const = 0;
|
||||
|
||||
virtual void _addScreenScale(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addAlphaTestInfo(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addZLutTexture(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addDepthInfo(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addDepthSource(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addRenderTarget(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addClampMode(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addPolygonOffset(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addScreenCoordsScale(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addColors(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addRectColor(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
virtual void _addLights(GLuint _program, UniformGroups &_uniforms) const = 0;
|
||||
|
||||
protected:
|
||||
const opengl::GLInfo & m_glInfo;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,397 @@
|
|||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <Config.h>
|
||||
#include "glsl_CombinerProgramUniformFactoryAccurate.h"
|
||||
#include <Graphics/Parameters.h>
|
||||
#include <Graphics/Context.h>
|
||||
|
||||
#include <Textures.h>
|
||||
#include <NoiseTexture.h>
|
||||
#include <FrameBuffer.h>
|
||||
#include <DisplayWindow.h>
|
||||
#include <Debugger.h>
|
||||
#include <GBI.h>
|
||||
#include <RSP.h>
|
||||
#include <gSP.h>
|
||||
#include <gDP.h>
|
||||
#include <VI.h>
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
namespace glsl {
|
||||
|
||||
class URasterInfo : public UniformGroup {
|
||||
public:
|
||||
URasterInfo(GLuint _program) {
|
||||
LocateUniform(uVertexOffset);
|
||||
LocateUniform(uTexCoordOffset[0]);
|
||||
LocateUniform(uTexCoordOffset[1]);
|
||||
LocateUniform(uUseTexCoordBounds);
|
||||
LocateUniform(uTexCoordBounds0);
|
||||
LocateUniform(uTexCoordBounds1);
|
||||
}
|
||||
|
||||
void update(bool _force) override {
|
||||
const bool isNativeRes = config.frameBufferEmulation.nativeResFactor == 1 && config.video.multisampling == 0;
|
||||
const bool isTexRect = dwnd().getDrawer().getDrawingState() == DrawingState::TexRect;
|
||||
const bool useTexCoordBounds = isTexRect && !isNativeRes && config.graphics2D.enableTexCoordBounds;
|
||||
/* At rasterization stage, the N64 places samples on the top left of the fragment while OpenGL */
|
||||
/* places them in the fragment center. As a result, a normal approach results in shifted texture */
|
||||
/* coordinates. In native resolution, this difference can be negated by shifting vertices by 0.5. */
|
||||
/* In higher resolutions, there are more samples than the game intends, so shifting is not very */
|
||||
/* effective. Still, an heuristic is applied to render texture rectangles as correctly as possible */
|
||||
/* in higher resolutions too. See issue #2324 for details. */
|
||||
const float vertexOffset = isNativeRes ? 0.5f : 0.0f;
|
||||
float texCoordOffset[2][2] = { 0.0f, 0.0f };
|
||||
if (isTexRect && !isNativeRes) {
|
||||
float scale[2] = { 0.0f, 0.0f };
|
||||
if (config.graphics2D.enableNativeResTexrects != 0 && gDP.otherMode.textureFilter != G_TF_POINT) {
|
||||
scale[0] = scale[1] = 1.0f;
|
||||
} else {
|
||||
scale[0] = scale[1] = static_cast<float>(config.frameBufferEmulation.nativeResFactor);
|
||||
}
|
||||
|
||||
for (int t = 0; t < 2; t++) {
|
||||
const CachedTexture* _pTexture = textureCache().current[t];
|
||||
if (_pTexture != nullptr) {
|
||||
if (config.frameBufferEmulation.nativeResFactor != 0) {
|
||||
if (gDP.otherMode.textureFilter != G_TF_POINT && gDP.otherMode.cycleType != G_CYC_COPY) {
|
||||
texCoordOffset[t][0] = -0.5f * gDP.lastTexRectInfo.dsdx;
|
||||
texCoordOffset[t][1] = -0.5f * gDP.lastTexRectInfo.dtdy;
|
||||
} else {
|
||||
texCoordOffset[t][0] = (gDP.lastTexRectInfo.dsdx >= 0.0f ? -0.5f / scale[0] : -1.0f + 0.5f / scale[0]) * gDP.lastTexRectInfo.dsdx;
|
||||
texCoordOffset[t][1] = (gDP.lastTexRectInfo.dtdy >= 0.0f ? -0.5f / scale[1] : -1.0f + 0.5f / scale[1]) * gDP.lastTexRectInfo.dtdy;
|
||||
}
|
||||
} else {
|
||||
texCoordOffset[t][0] = (gDP.lastTexRectInfo.dsdx >= 0.0f ? 0.0f : -1.0f) * gDP.lastTexRectInfo.dsdx;
|
||||
texCoordOffset[t][1] = (gDP.lastTexRectInfo.dtdy >= 0.0f ? 0.0f : -1.0f) * gDP.lastTexRectInfo.dtdy;
|
||||
if (gDP.otherMode.textureFilter != G_TF_POINT && gDP.otherMode.cycleType != G_CYC_COPY) {
|
||||
texCoordOffset[t][0] -= 0.5f;
|
||||
texCoordOffset[t][1] -= 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Hack for framebuffer textures. See #519 and #2112 */
|
||||
if ((config.generalEmulation.hacks & hack_fbTextureOffset) != 0) {
|
||||
for (int t = 0; t < 2; t++) {
|
||||
const CachedTexture* _pTexture = textureCache().current[t];
|
||||
if (_pTexture != nullptr) {
|
||||
if (gDP.otherMode.textureFilter != G_TF_POINT && _pTexture->frameBufferTexture != CachedTexture::fbNone) {
|
||||
texCoordOffset[t][0] -= 1.0f;
|
||||
texCoordOffset[t][1] -= 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
float tcbounds[2][4] = {};
|
||||
if (useTexCoordBounds) {
|
||||
f32 uls, lrs, ult, lrt, S, T;
|
||||
for (int t = 0; t < 2; t++) {
|
||||
const CachedTexture * _pTexture = textureCache().current[t];
|
||||
if (_pTexture != nullptr) {
|
||||
S = _FIXED2FLOAT(gDP.lastTexRectInfo.s, 5);
|
||||
T = _FIXED2FLOAT(gDP.lastTexRectInfo.t, 5);
|
||||
uls = S + (ceilf(gDP.lastTexRectInfo.ulx) - gDP.lastTexRectInfo.ulx) * gDP.lastTexRectInfo.dsdx;
|
||||
lrs = S + (ceilf(gDP.lastTexRectInfo.lrx) - gDP.lastTexRectInfo.ulx - 1.0f) * gDP.lastTexRectInfo.dsdx;
|
||||
ult = T + (ceilf(gDP.lastTexRectInfo.uly) - gDP.lastTexRectInfo.uly) * gDP.lastTexRectInfo.dtdy;
|
||||
lrt = T + (ceilf(gDP.lastTexRectInfo.lry) - gDP.lastTexRectInfo.uly - 1.0f) * gDP.lastTexRectInfo.dtdy;
|
||||
tcbounds[t][0] = fmin(uls, lrs);
|
||||
tcbounds[t][1] = fmin(ult, lrt);
|
||||
tcbounds[t][2] = fmax(uls, lrs);
|
||||
tcbounds[t][3] = fmax(ult, lrt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uVertexOffset.set(vertexOffset, vertexOffset, _force);
|
||||
uTexCoordOffset[0].set(texCoordOffset[0][0], texCoordOffset[0][1], _force);
|
||||
uTexCoordOffset[1].set(texCoordOffset[1][0], texCoordOffset[1][1], _force);
|
||||
uUseTexCoordBounds.set(useTexCoordBounds ? 1 : 0, _force);
|
||||
uTexCoordBounds0.set(tcbounds[0], _force);
|
||||
uTexCoordBounds1.set(tcbounds[1], _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv2Uniform uVertexOffset;
|
||||
fv2Uniform uTexCoordOffset[2];
|
||||
iUniform uUseTexCoordBounds;
|
||||
fv4Uniform uTexCoordBounds0;
|
||||
fv4Uniform uTexCoordBounds1;
|
||||
};
|
||||
|
||||
class UMipmap : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UMipmap(GLuint _program) {
|
||||
LocateUniform(uMinLod);
|
||||
LocateUniform(uMaxTile);
|
||||
LocateUniform(uEnableLod);
|
||||
LocateUniform(uTextureDetail);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uMinLod.set(gDP.primColor.m, _force);
|
||||
const CachedTexture * _pTexture = textureCache().current[1];
|
||||
if (_pTexture == nullptr)
|
||||
uMaxTile.set(gSP.texture.level, _force);
|
||||
else
|
||||
uMaxTile.set(_pTexture->max_level > 0 ? gSP.texture.level : std::min(gSP.texture.level, 1u), _force);
|
||||
const int uCalcLOD = (gDP.otherMode.textureLOD == G_TL_LOD) ? 1 : 0;
|
||||
uEnableLod.set(uCalcLOD, _force);
|
||||
uTextureDetail.set(gDP.otherMode.textureDetail, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fUniform uMinLod;
|
||||
iUniform uMaxTile;
|
||||
iUniform uEnableLod;
|
||||
iUniform uTextureDetail;
|
||||
};
|
||||
|
||||
class UTextureSize : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UTextureSize(GLuint _program, bool _useT0, bool _useT1)
|
||||
: m_useT0(_useT0)
|
||||
, m_useT1(_useT1)
|
||||
{
|
||||
LocateUniform(uTextureSize[0]);
|
||||
LocateUniform(uTextureSize[1]);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
TextureCache & cache = textureCache();
|
||||
if (m_useT0 && cache.current[0] != nullptr)
|
||||
uTextureSize[0].set(static_cast<float>(cache.current[0]->width),
|
||||
static_cast<float>(cache.current[0]->height), _force);
|
||||
if (m_useT1 && cache.current[1] != nullptr) {
|
||||
CachedTexture * pTexture = cache.current[1];
|
||||
if (pTexture->max_level == 0)
|
||||
uTextureSize[1].set(static_cast<float>(pTexture->width),
|
||||
static_cast<float>(pTexture->height), _force);
|
||||
else
|
||||
uTextureSize[1].set(static_cast<float>(pTexture->mipmapAtlasWidth),
|
||||
static_cast<float>(pTexture->mipmapAtlasHeight), _force);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
fv2Uniform uTextureSize[2];
|
||||
bool m_useT0;
|
||||
bool m_useT1;
|
||||
};
|
||||
|
||||
class UTextureParams : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UTextureParams(GLuint _program, bool _useT0, bool _useT1)
|
||||
{
|
||||
m_useTile[0] = _useT0;
|
||||
m_useTile[1] = _useT1;
|
||||
LocateUniform(uTexScale);
|
||||
LocateUniform(uCacheFrameBuffer);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
int nFB[2] = { 0, 0 };
|
||||
TextureCache & cache = textureCache();
|
||||
for (u32 t = 0; t < 2; ++t) {
|
||||
if (!m_useTile[t])
|
||||
continue;
|
||||
CachedTexture *_pTexture = cache.current[t];
|
||||
if (_pTexture != nullptr) {
|
||||
nFB[t] = _pTexture->frameBufferTexture;
|
||||
}
|
||||
}
|
||||
|
||||
uCacheFrameBuffer.set(nFB[0], nFB[1], _force);
|
||||
uTexScale.set(gSP.texture.scales, gSP.texture.scalet, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_useTile[2];
|
||||
fv2Uniform uTexScale;
|
||||
iv2Uniform uCacheFrameBuffer;
|
||||
};
|
||||
|
||||
class UTextureEngine : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UTextureEngine(GLuint _program, bool _useT0, bool _useT1)
|
||||
{
|
||||
m_useTile[0] = _useT0;
|
||||
m_useTile[1] = _useT1;
|
||||
LocateUniform(uTexWrap[0]);
|
||||
LocateUniform(uTexWrap[1]);
|
||||
LocateUniform(uTexClamp[0]);
|
||||
LocateUniform(uTexClamp[1]);
|
||||
LocateUniform(uTexWrapEn[0]);
|
||||
LocateUniform(uTexWrapEn[1]);
|
||||
LocateUniform(uTexClampEn[0]);
|
||||
LocateUniform(uTexClampEn[1]);
|
||||
LocateUniform(uTexMirrorEn[0]);
|
||||
LocateUniform(uTexMirrorEn[1]);
|
||||
LocateUniform(uTexSize[0]);
|
||||
LocateUniform(uTexSize[1]);
|
||||
LocateUniform(uShiftScale[0]);
|
||||
LocateUniform(uShiftScale[1]);
|
||||
LocateUniform(uTexOffset[0]);
|
||||
LocateUniform(uTexOffset[1]);
|
||||
LocateUniform(uHDRatio[0]);
|
||||
LocateUniform(uHDRatio[1]);
|
||||
LocateUniform(uCacheOffset[0]);
|
||||
LocateUniform(uCacheOffset[1]);
|
||||
LocateUniform(uBilinearOffset);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
std::array<f32, 2> aTexWrap[2] = { { 1024.0f, 1024.0f }, { 1024.0f, 1024.0f } };
|
||||
std::array<f32, 2> aTexClamp[2] = { { 1024.0f, 1024.0f }, { 1024.0f, 1024.0f } };
|
||||
std::array<f32, 2> aTexWrapEn[2] = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
|
||||
std::array<f32, 2> aTexClampEn[2] = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
|
||||
std::array<f32, 2> aTexMirrorEn[2] = { { 0.0f, 0.0f }, { 0.0f,0.0f }};
|
||||
std::array<f32, 2> aTexSize[2] = { { 1024.0f, 1024.0f }, { 1024.0f, 1024.0f } };
|
||||
|
||||
std::array<f32, 2> aShiftScale[2] = { { 1.0f, 1.0f }, { 1.0f,1.0f } };
|
||||
std::array<f32, 2> aTexOffset[2] = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
|
||||
|
||||
std::array<f32, 2> aHDRatio[2] = { { 1.0f, 1.0f }, { 1.0f, 1.0f } };
|
||||
std::array<f32, 2> aCacheOffset[2] = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
|
||||
|
||||
const float bilinearOffset = gDP.otherMode.textureFilter != G_TF_POINT && gDP.otherMode.cycleType != G_CYC_COPY ? 0.5f : 0.0f;
|
||||
uBilinearOffset.set(bilinearOffset, bilinearOffset, _force);
|
||||
|
||||
TextureCache & cache = textureCache();
|
||||
for (u32 t = 0; t < 2; ++t) {
|
||||
if (!m_useTile[t])
|
||||
continue;
|
||||
|
||||
const gDPTile * pTile = gSP.textureTile[t];
|
||||
CachedTexture * pTexture = cache.current[t];
|
||||
if (pTile == nullptr || pTexture == nullptr)
|
||||
continue;
|
||||
|
||||
aTexSize[t][0] = pTexture->width * pTexture->hdRatioS;
|
||||
aTexSize[t][1] = pTexture->height * pTexture->hdRatioT;
|
||||
|
||||
aShiftScale[t][0] = pTile->shifts > 10 ? static_cast<f32>(1 << (16 - pTile->shifts)) : 1.0f / static_cast<f32>(1 << pTile->shifts);
|
||||
aShiftScale[t][1] = pTile->shiftt > 10 ? static_cast<f32>(1 << (16 - pTile->shiftt)) : 1.0f / static_cast<f32>(1 << pTile->shiftt);
|
||||
|
||||
if (pTile->textureMode != TEXTUREMODE_BGIMAGE && pTile->textureMode != TEXTUREMODE_FRAMEBUFFER_BG) {
|
||||
aTexOffset[t][0] = pTile->fuls;
|
||||
aTexOffset[t][1] = pTile->fult;
|
||||
}
|
||||
|
||||
aHDRatio[t][0] = pTexture->hdRatioS;
|
||||
aHDRatio[t][1] = pTexture->hdRatioT;
|
||||
|
||||
aCacheOffset[t][0] = pTexture->offsetS * pTexture->hdRatioS;
|
||||
aCacheOffset[t][1] = pTexture->offsetT * pTexture->hdRatioT;
|
||||
|
||||
/* Not sure if special treatment of framebuffer textures is correct */
|
||||
if (pTexture->frameBufferTexture != CachedTexture::fbNone)
|
||||
{
|
||||
aTexClamp[t][0] = f32(pTexture->width) * pTexture->hdRatioS - 1.0f;
|
||||
aTexClamp[t][1] = f32(pTexture->height) * pTexture->hdRatioT - 1.0f;
|
||||
aTexWrapEn[t][0] = 0.0;
|
||||
aTexWrapEn[t][1] = 0.0;
|
||||
aTexClampEn[t][0] = 1.0;
|
||||
aTexClampEn[t][1] = 1.0;
|
||||
aTexMirrorEn[t][0] = 0.0;
|
||||
aTexMirrorEn[t][1] = 0.0;
|
||||
} else if (pTile->textureMode != TEXTUREMODE_NORMAL || g_debugger.isDebugMode()) {
|
||||
aTexWrapEn[t][0] = 0.0;
|
||||
aTexWrapEn[t][1] = 0.0;
|
||||
aTexClampEn[t][0] = 0.0;
|
||||
aTexClampEn[t][1] = 0.0;
|
||||
aTexMirrorEn[t][0] = 0.0;
|
||||
aTexMirrorEn[t][1] = 0.0;
|
||||
} else {
|
||||
aTexWrap[t][0] = f32(1 << pTile->masks) * pTexture->hdRatioS;
|
||||
aTexWrap[t][1] = f32(1 << pTile->maskt) * pTexture->hdRatioT;
|
||||
aTexClamp[t][0] = f32(pTile->lrs - pTile->uls + 1) * pTexture->hdRatioS - 1.0f;
|
||||
aTexClamp[t][1] = f32(pTile->lrt - pTile->ult + 1) * pTexture->hdRatioT - 1.0f;
|
||||
aTexWrapEn[t][0] = f32(pTile->masks == 0 ? 0 : 1);
|
||||
aTexWrapEn[t][1] = f32(pTile->maskt == 0 ? 0 : 1);
|
||||
aTexClampEn[t][0] = f32(gDP.otherMode.cycleType == G_CYC_COPY ? 0 : (pTile->masks == 0 ? 1 : pTile->clamps));
|
||||
aTexClampEn[t][1] = f32(gDP.otherMode.cycleType == G_CYC_COPY ? 0 : (pTile->maskt == 0 ? 1 : pTile->clampt));
|
||||
aTexMirrorEn[t][0] = f32(pTile->masks == 0 ? 0 : pTile->mirrors);
|
||||
aTexMirrorEn[t][1] = f32(pTile->maskt == 0 ? 0 : pTile->mirrort);
|
||||
}
|
||||
|
||||
uTexWrap[t].set(aTexWrap[t][0], aTexWrap[t][1], _force);
|
||||
uTexClamp[t].set(aTexClamp[t][0], aTexClamp[t][1], _force);
|
||||
uTexWrapEn[t].set(aTexWrapEn[t][0], aTexWrapEn[t][1], _force);
|
||||
uTexWrapEn[t].set(aTexWrapEn[t][0], aTexWrapEn[t][1], _force);
|
||||
uTexClampEn[t].set(aTexClampEn[t][0], aTexClampEn[t][1], _force);
|
||||
uTexMirrorEn[t].set(aTexMirrorEn[t][0], aTexMirrorEn[t][1], _force);
|
||||
uTexSize[t].set(aTexSize[t][0], aTexSize[t][1], _force);
|
||||
uShiftScale[t].set(aShiftScale[t][0], aShiftScale[t][1], _force);
|
||||
uTexOffset[t].set(aTexOffset[t][0], aTexOffset[t][1], _force);
|
||||
uHDRatio[t].set(aHDRatio[t][0], aHDRatio[t][1], _force);
|
||||
uCacheOffset[t].set(aCacheOffset[t][0], aCacheOffset[t][1], _force);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_useTile[2];
|
||||
fv2Uniform uTexWrap[2];
|
||||
fv2Uniform uTexClamp[2];
|
||||
fv2Uniform uTexWrapEn[2];
|
||||
fv2Uniform uTexClampEn[2];
|
||||
fv2Uniform uTexMirrorEn[2];
|
||||
fv2Uniform uTexSize[2];
|
||||
fv2Uniform uShiftScale[2];
|
||||
fv2Uniform uTexOffset[2];
|
||||
fv2Uniform uHDRatio[2];
|
||||
fv2Uniform uCacheOffset[2];
|
||||
fv2Uniform uBilinearOffset;
|
||||
};
|
||||
|
||||
/*---------------CombinerProgramUniformFactoryCommon-------------*/
|
||||
|
||||
void CombinerProgramUniformFactoryAccurate::_addRasterInfo(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new URasterInfo(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryAccurate::_addMipmap(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UMipmap(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryAccurate::_addMipmap2(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryAccurate::_addTextureSize(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const
|
||||
{
|
||||
_uniforms.emplace_back(new UTextureSize(_program, _usesTile0, _usesTile1));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryAccurate::_addTextureParams(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const
|
||||
{
|
||||
_uniforms.emplace_back(new UTextureParams(_program, _usesTile0, _usesTile1));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryAccurate::_addClampWrapMirrorEngine(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const
|
||||
{
|
||||
_uniforms.emplace_back(new UTextureEngine(_program, _usesTile0, _usesTile1));
|
||||
}
|
||||
|
||||
CombinerProgramUniformFactoryAccurate::CombinerProgramUniformFactoryAccurate(const opengl::GLInfo & _glInfo)
|
||||
: CombinerProgramUniformFactoryCommon(_glInfo)
|
||||
, m_glInfo(_glInfo)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
#include <Graphics/OpenGLContext/opengl_GLInfo.h>
|
||||
#include "glsl_CombinerProgramImpl.h"
|
||||
#include "glsl_CombinerProgramUniformFactoryCommon.h"
|
||||
|
||||
namespace glsl {
|
||||
class CombinerProgramUniformFactoryAccurate : public CombinerProgramUniformFactoryCommon {
|
||||
|
||||
public:
|
||||
CombinerProgramUniformFactoryAccurate(const opengl::GLInfo & _glInfo);
|
||||
private:
|
||||
|
||||
virtual void _addRasterInfo(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
virtual void _addMipmap(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
virtual void _addMipmap2(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
virtual void _addTextureSize(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const override;
|
||||
|
||||
virtual void _addTextureParams(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const override;
|
||||
|
||||
virtual void _addClampWrapMirrorEngine(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const override;
|
||||
|
||||
const opengl::GLInfo &m_glInfo;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,914 @@
|
|||
#include <Config.h>
|
||||
#include "glsl_CombinerProgramUniformFactoryCommon.h"
|
||||
#include <Graphics/Parameters.h>
|
||||
#include <Graphics/Context.h>
|
||||
|
||||
#include <Textures.h>
|
||||
#include <NoiseTexture.h>
|
||||
#include <FrameBuffer.h>
|
||||
#include <DisplayWindow.h>
|
||||
#include <Debugger.h>
|
||||
#include <GBI.h>
|
||||
#include <RSP.h>
|
||||
#include <gSP.h>
|
||||
#include <gDP.h>
|
||||
#include <VI.h>
|
||||
|
||||
namespace glsl {
|
||||
|
||||
/*---------------UniformGroup-------------*/
|
||||
|
||||
class UNoiseTex : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UNoiseTex(GLuint _program) {
|
||||
LocateUniform(uTexNoise);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uTexNoise.set(int(graphics::textureIndices::NoiseTex), _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uTexNoise;
|
||||
};
|
||||
|
||||
class UDepthTex : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UDepthTex(GLuint _program) {
|
||||
LocateUniform(uDepthTex);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uDepthTex.set(int(graphics::textureIndices::DepthTex), _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uDepthTex;
|
||||
};
|
||||
|
||||
class UZLutTexture : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UZLutTexture(GLuint _program) {
|
||||
LocateUniform(uZlutImage);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uZlutImage.set(int(graphics::textureIndices::ZLUTTex), _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uZlutImage;
|
||||
};
|
||||
|
||||
class UTextures : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UTextures(GLuint _program) {
|
||||
LocateUniform(uTex0);
|
||||
LocateUniform(uTex1);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uTex0.set(0, _force);
|
||||
uTex1.set(1, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uTex0;
|
||||
iUniform uTex1;
|
||||
};
|
||||
|
||||
class UMSAATextures : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UMSAATextures(GLuint _program) {
|
||||
LocateUniform(uMSTex0);
|
||||
LocateUniform(uMSTex1);
|
||||
LocateUniform(uMSAASamples);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uMSTex0.set(int(graphics::textureIndices::MSTex[0]), _force);
|
||||
uMSTex1.set(int(graphics::textureIndices::MSTex[1]), _force);
|
||||
uMSAASamples.set(config.video.multisampling, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uMSTex0;
|
||||
iUniform uMSTex1;
|
||||
iUniform uMSAASamples;
|
||||
};
|
||||
|
||||
class UScreenSpaceTriangleInfo : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UScreenSpaceTriangleInfo(GLuint _program) {
|
||||
LocateUniform(uScreenSpaceTriangle);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uScreenSpaceTriangle.set(
|
||||
(dwnd().getDrawer().getDrawingState() == DrawingState::ScreenSpaceTriangle) ? 1 : 0, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uScreenSpaceTriangle;
|
||||
};
|
||||
|
||||
class UFrameBufferInfo : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UFrameBufferInfo(GLuint _program) {
|
||||
LocateUniform(uFbMonochrome);
|
||||
LocateUniform(uFbFixedAlpha);
|
||||
LocateUniform(uMSTexEnabled);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
int nFbMonochromeMode0 = 0, nFbMonochromeMode1 = 0;
|
||||
int nFbFixedAlpha0 = 0, nFbFixedAlpha1 = 0;
|
||||
int nMSTex0Enabled = 0, nMSTex1Enabled = 0;
|
||||
TextureCache & cache = textureCache();
|
||||
if (cache.current[0] != nullptr && cache.current[0]->frameBufferTexture != CachedTexture::fbNone) {
|
||||
if (cache.current[0]->size == G_IM_SIZ_8b) {
|
||||
nFbMonochromeMode0 = 1;
|
||||
if (gDP.otherMode.imageRead == 0)
|
||||
nFbFixedAlpha0 = 1;
|
||||
} else if (gSP.textureTile[0]->size == G_IM_SIZ_16b && gSP.textureTile[0]->format == G_IM_FMT_IA) {
|
||||
nFbMonochromeMode0 = 2;
|
||||
} else if ((config.generalEmulation.hacks & hack_ZeldaMonochrome) != 0 &&
|
||||
cache.current[0]->size == G_IM_SIZ_16b &&
|
||||
gSP.textureTile[0]->size == G_IM_SIZ_8b &&
|
||||
gSP.textureTile[0]->format == G_IM_FMT_CI) {
|
||||
// Zelda monochrome effect
|
||||
nFbMonochromeMode0 = 3;
|
||||
nFbMonochromeMode1 = 3;
|
||||
}
|
||||
|
||||
nMSTex0Enabled = cache.current[0]->frameBufferTexture == CachedTexture::fbMultiSample ? 1 : 0;
|
||||
}
|
||||
if (cache.current[1] != nullptr && cache.current[1]->frameBufferTexture != CachedTexture::fbNone) {
|
||||
if (cache.current[1]->size == G_IM_SIZ_8b) {
|
||||
nFbMonochromeMode1 = 1;
|
||||
if (gDP.otherMode.imageRead == 0)
|
||||
nFbFixedAlpha1 = 1;
|
||||
}
|
||||
else if (gSP.textureTile[1]->size == G_IM_SIZ_16b && gSP.textureTile[1]->format == G_IM_FMT_IA)
|
||||
nFbMonochromeMode1 = 2;
|
||||
nMSTex1Enabled = cache.current[1]->frameBufferTexture == CachedTexture::fbMultiSample ? 1 : 0;
|
||||
}
|
||||
uFbMonochrome.set(nFbMonochromeMode0, nFbMonochromeMode1, _force);
|
||||
uFbFixedAlpha.set(nFbFixedAlpha0, nFbFixedAlpha1, _force);
|
||||
uMSTexEnabled.set(nMSTex0Enabled, nMSTex1Enabled, _force);
|
||||
gDP.changed &= ~CHANGED_FB_TEXTURE;
|
||||
}
|
||||
|
||||
private:
|
||||
iv2Uniform uFbMonochrome;
|
||||
iv2Uniform uFbFixedAlpha;
|
||||
iv2Uniform uMSTexEnabled;
|
||||
};
|
||||
|
||||
|
||||
class UFog : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UFog(GLuint _program) {
|
||||
LocateUniform(uFogUsage);
|
||||
LocateUniform(uFogScale);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
if (RSP.LLE) {
|
||||
uFogUsage.set(0, _force);
|
||||
return;
|
||||
}
|
||||
|
||||
int nFogUsage = ((gSP.geometryMode & G_FOG) != 0) ? 1 : 0;
|
||||
if (GBI.getMicrocodeType() == F3DAM) {
|
||||
const s16 fogMode = ((gSP.geometryMode >> 13) & 9) + 0xFFF8;
|
||||
if (fogMode == 0)
|
||||
nFogUsage = 1;
|
||||
else if (fogMode > 0)
|
||||
nFogUsage = 2;
|
||||
}
|
||||
uFogUsage.set(nFogUsage, _force);
|
||||
uFogScale.set(gSP.fog.multiplierf, gSP.fog.offsetf, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uFogUsage;
|
||||
fv2Uniform uFogScale;
|
||||
};
|
||||
|
||||
class UBlendMode1Cycle : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UBlendMode1Cycle(GLuint _program) {
|
||||
LocateUniform(uBlendMux1);
|
||||
LocateUniform(uForceBlendCycle1);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uBlendMux1.set(gDP.otherMode.c1_m1a,
|
||||
gDP.otherMode.c1_m1b,
|
||||
gDP.otherMode.c1_m2a,
|
||||
gDP.otherMode.c1_m2b,
|
||||
_force);
|
||||
|
||||
const int forceBlend1 = (int)gDP.otherMode.forceBlender;
|
||||
uForceBlendCycle1.set(forceBlend1, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
i4Uniform uBlendMux1;
|
||||
iUniform uForceBlendCycle1;
|
||||
};
|
||||
|
||||
class UBlendMode2Cycle : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UBlendMode2Cycle(GLuint _program) {
|
||||
LocateUniform(uBlendMux1);
|
||||
LocateUniform(uBlendMux2);
|
||||
LocateUniform(uForceBlendCycle1);
|
||||
LocateUniform(uForceBlendCycle2);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uBlendMux1.set(gDP.otherMode.c1_m1a,
|
||||
gDP.otherMode.c1_m1b,
|
||||
gDP.otherMode.c1_m2a,
|
||||
gDP.otherMode.c1_m2b,
|
||||
_force);
|
||||
|
||||
uBlendMux2.set(gDP.otherMode.c2_m1a,
|
||||
gDP.otherMode.c2_m1b,
|
||||
gDP.otherMode.c2_m2a,
|
||||
gDP.otherMode.c2_m2b,
|
||||
_force);
|
||||
|
||||
const int forceBlend1 = 1;
|
||||
uForceBlendCycle1.set(forceBlend1, _force);
|
||||
const int forceBlend2 = gDP.otherMode.forceBlender;
|
||||
uForceBlendCycle2.set(forceBlend2, _force);
|
||||
|
||||
if (!(graphics::Context::DualSourceBlending || graphics::Context::FramebufferFetchColor) || dwnd().getDrawer().isTexrectDrawerMode()) {
|
||||
// Modes, which shader blender can't emulate
|
||||
const u32 mode = _SHIFTR(gDP.otherMode.l, 16, 16);
|
||||
switch (mode) {
|
||||
case 0x0040:
|
||||
// Mia Hamm Soccer
|
||||
// clr_in * a_in + clr_mem * (1-a)
|
||||
// clr_in * a_in + clr_in * (1-a)
|
||||
case 0x0050:
|
||||
// A Bug's Life
|
||||
// clr_in * a_in + clr_mem * (1-a)
|
||||
// clr_in * a_in + clr_mem * (1-a)
|
||||
uForceBlendCycle1.set(0, _force);
|
||||
uForceBlendCycle2.set(0, _force);
|
||||
break;
|
||||
case 0x0150:
|
||||
// Tony Hawk
|
||||
// clr_in * a_in + clr_mem * (1-a)
|
||||
// clr_in * a_fog + clr_mem * (1-a_fog)
|
||||
if ((config.generalEmulation.hacks & hack_TonyHawk) != 0) {
|
||||
uForceBlendCycle1.set(0, _force);
|
||||
uForceBlendCycle2.set(0, _force);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
i4Uniform uBlendMux1;
|
||||
i4Uniform uBlendMux2;
|
||||
iUniform uForceBlendCycle1;
|
||||
iUniform uForceBlendCycle2;
|
||||
};
|
||||
|
||||
class UBlendCvg : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UBlendCvg(GLuint _program) {
|
||||
LocateUniform(uCvgDest);
|
||||
LocateUniform(uBlendAlphaMode);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uCvgDest.set(gDP.otherMode.cvgDest, _force);
|
||||
if (dwnd().getDrawer().isTexrectDrawerMode())
|
||||
uBlendAlphaMode.set(2, _force); // No alpha blend in texrect drawing mode
|
||||
else
|
||||
uBlendAlphaMode.set(gDP.otherMode.forceBlender, _force);
|
||||
}
|
||||
private:
|
||||
iUniform uCvgDest;
|
||||
iUniform uBlendAlphaMode;
|
||||
};
|
||||
|
||||
class UDitherMode : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UDitherMode(GLuint _program, bool _usesNoise)
|
||||
: m_usesNoise(_usesNoise)
|
||||
{
|
||||
LocateUniform(uAlphaCompareMode);
|
||||
LocateUniform(uAlphaDitherMode);
|
||||
LocateUniform(uColorDitherMode);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
if (gDP.otherMode.cycleType < G_CYC_COPY) {
|
||||
uAlphaCompareMode.set(gDP.otherMode.alphaCompare, _force);
|
||||
uAlphaDitherMode.set(gDP.otherMode.alphaDither, _force);
|
||||
uColorDitherMode.set(gDP.otherMode.colorDither, _force);
|
||||
}
|
||||
else {
|
||||
uAlphaCompareMode.set(0, _force);
|
||||
uAlphaDitherMode.set(0, _force);
|
||||
uColorDitherMode.set(0, _force);
|
||||
}
|
||||
|
||||
bool updateNoiseTex = m_usesNoise;
|
||||
updateNoiseTex |= (gDP.otherMode.cycleType < G_CYC_COPY) && (gDP.otherMode.colorDither == G_CD_NOISE || gDP.otherMode.alphaDither == G_AD_NOISE || gDP.otherMode.alphaCompare == G_AC_DITHER);
|
||||
if (updateNoiseTex)
|
||||
g_noiseTexture.update();
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uAlphaCompareMode;
|
||||
iUniform uAlphaDitherMode;
|
||||
iUniform uColorDitherMode;
|
||||
bool m_usesNoise;
|
||||
};
|
||||
|
||||
class UScreenScale : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UScreenScale(GLuint _program) {
|
||||
LocateUniform(uScreenScale);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
if (dwnd().getDrawer().isTexrectDrawerMode()) {
|
||||
uScreenScale.set(1.0f, 1.0f, _force);
|
||||
return;
|
||||
}
|
||||
|
||||
FrameBuffer * pBuffer = frameBufferList().getCurrent();
|
||||
if (pBuffer == nullptr)
|
||||
uScreenScale.set(dwnd().getScaleX(), dwnd().getScaleY(), _force);
|
||||
else
|
||||
uScreenScale.set(pBuffer->m_scale, pBuffer->m_scale, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv2Uniform uScreenScale;
|
||||
};
|
||||
|
||||
class UTexturePersp : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UTexturePersp(GLuint _program) {
|
||||
LocateUniform(uTexturePersp);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
const u32 texturePersp = (RSP.LLE || GBI.isTexturePersp()) ? gDP.otherMode.texturePersp : 1U;
|
||||
uTexturePersp.set(texturePersp, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uTexturePersp;
|
||||
};
|
||||
|
||||
class UTextureFetchMode : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UTextureFetchMode(GLuint _program) {
|
||||
LocateUniform(uTextureFilterMode);
|
||||
LocateUniform(uTextureFormat);
|
||||
LocateUniform(uTextureConvert);
|
||||
LocateUniform(uConvertParams);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
int textureFilter = gDP.otherMode.textureFilter;
|
||||
uTextureFilterMode.set(textureFilter, _force);
|
||||
uTextureFormat.set(gSP.textureTile[0]->format, gSP.textureTile[1]->format, _force);
|
||||
uTextureConvert.set(gDP.otherMode.convert_one, _force);
|
||||
if (gDP.otherMode.bi_lerp0 == 0 || gDP.otherMode.bi_lerp1 == 0)
|
||||
uConvertParams.set(gDP.convert.k0, gDP.convert.k1, gDP.convert.k2, gDP.convert.k3, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uTextureFilterMode;
|
||||
iv2Uniform uTextureFormat;
|
||||
iUniform uTextureConvert;
|
||||
i4Uniform uConvertParams;
|
||||
};
|
||||
|
||||
class UAlphaTestInfo : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UAlphaTestInfo(GLuint _program) {
|
||||
LocateUniform(uEnableAlphaTest);
|
||||
LocateUniform(uAlphaCvgSel);
|
||||
LocateUniform(uCvgXAlpha);
|
||||
LocateUniform(uAlphaTestValue);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
if (gDP.otherMode.cycleType == G_CYC_FILL) {
|
||||
uEnableAlphaTest.set(0, _force);
|
||||
uAlphaCvgSel.set(0, _force);
|
||||
|
||||
} else if (gDP.otherMode.cycleType == G_CYC_COPY) {
|
||||
uAlphaCvgSel.set(0, _force);
|
||||
if (gDP.otherMode.alphaCompare & G_AC_THRESHOLD) {
|
||||
uEnableAlphaTest.set(1, _force);
|
||||
uAlphaTestValue.set(0.5f, _force);
|
||||
} else {
|
||||
uEnableAlphaTest.set(0, _force);
|
||||
}
|
||||
} else if ((gDP.otherMode.alphaCompare & G_AC_THRESHOLD) != 0) {
|
||||
uEnableAlphaTest.set(1, _force);
|
||||
uAlphaTestValue.set(gDP.blendColor.a, _force);
|
||||
uAlphaCvgSel.set(gDP.otherMode.alphaCvgSel, _force);
|
||||
} else {
|
||||
uEnableAlphaTest.set(0, _force);
|
||||
uAlphaCvgSel.set(gDP.otherMode.alphaCvgSel, _force);
|
||||
}
|
||||
|
||||
uCvgXAlpha.set(gDP.otherMode.cvgXAlpha, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uEnableAlphaTest;
|
||||
iUniform uAlphaCvgSel;
|
||||
iUniform uCvgXAlpha;
|
||||
fUniform uAlphaTestValue;
|
||||
};
|
||||
|
||||
class UViewportInfo : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UViewportInfo(GLuint _program) {
|
||||
LocateUniform(uVTrans);
|
||||
LocateUniform(uVScale);
|
||||
LocateUniform(uAdjustTrans);
|
||||
LocateUniform(uAdjustScale);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
const bool isOrthographicProjection = gSP.matrix.projection[3][2] == -1.f;
|
||||
float adjustTrans[2] = { 0.0f, 0.0f };
|
||||
float adjustScale[2] = { 1.0f, 1.0f };
|
||||
if (dwnd().isAdjustScreen() && (gDP.colorImage.width > VI.width * 98 / 100)) {
|
||||
if (isOrthographicProjection) {
|
||||
adjustScale[1] = 1.0f / dwnd().getAdjustScale();
|
||||
adjustTrans[1] = static_cast<f32>(gDP.colorImage.width) * 3.0f / 4.0f * (1.0f - adjustScale[1]) / 2.0f;
|
||||
} else {
|
||||
adjustScale[0] = dwnd().getAdjustScale();
|
||||
adjustTrans[0] = static_cast<f32>(gDP.colorImage.width) * (1.0f - adjustScale[0]) / 2.0f;
|
||||
}
|
||||
}
|
||||
uVTrans.set(gSP.viewport.vtrans[0], gSP.viewport.vtrans[1], _force);
|
||||
uVScale.set(gSP.viewport.vscale[0], -gSP.viewport.vscale[1], _force);
|
||||
uAdjustTrans.set(adjustTrans[0], adjustTrans[1], _force);
|
||||
uAdjustScale.set(adjustScale[0], adjustScale[1], _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv2Uniform uVTrans;
|
||||
fv2Uniform uVScale;
|
||||
fv2Uniform uAdjustTrans;
|
||||
fv2Uniform uAdjustScale;
|
||||
};
|
||||
|
||||
class UDepthScale : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UDepthScale(GLuint _program) {
|
||||
LocateUniform(uDepthScale);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
if (RSP.LLE)
|
||||
uDepthScale.set(0.5f, 0.5f, _force);
|
||||
else
|
||||
uDepthScale.set(gSP.viewport.vscale[2], gSP.viewport.vtrans[2], _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv2Uniform uDepthScale;
|
||||
};
|
||||
|
||||
class UDepthInfo : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UDepthInfo(GLuint _program) {
|
||||
LocateUniform(uEnableDepth);
|
||||
LocateUniform(uEnableDepthCompare);
|
||||
LocateUniform(uEnableDepthUpdate);
|
||||
LocateUniform(uDepthMode);
|
||||
LocateUniform(uDepthSource);
|
||||
LocateUniform(uPrimDepth);
|
||||
LocateUniform(uDeltaZ);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
FrameBuffer * pBuffer = frameBufferList().getCurrent();
|
||||
if (pBuffer == nullptr || pBuffer->m_pDepthBuffer == nullptr)
|
||||
return;
|
||||
|
||||
const bool nDepthEnabled = ((gSP.geometryMode & G_ZBUFFER) || gDP.otherMode.depthSource == G_ZS_PRIM) &&
|
||||
gDP.otherMode.cycleType <= G_CYC_2CYCLE;
|
||||
uEnableDepth.set(nDepthEnabled ? 1 : 0, _force);
|
||||
if (nDepthEnabled) {
|
||||
uEnableDepthCompare.set(gDP.otherMode.depthCompare, _force);
|
||||
uEnableDepthUpdate.set(gDP.otherMode.depthUpdate, _force);
|
||||
} else {
|
||||
uEnableDepthCompare.set(0, _force);
|
||||
uEnableDepthUpdate.set(0, _force);
|
||||
}
|
||||
uDepthMode.set(gDP.otherMode.depthMode, _force);
|
||||
uDepthSource.set(gDP.otherMode.depthSource, _force);
|
||||
if (gDP.otherMode.depthSource == G_ZS_PRIM) {
|
||||
uDeltaZ.set(gDP.primDepth.deltaZ, _force);
|
||||
uPrimDepth.set(gDP.primDepth.z, _force);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uEnableDepth;
|
||||
iUniform uEnableDepthCompare;
|
||||
iUniform uEnableDepthUpdate;
|
||||
iUniform uDepthMode;
|
||||
iUniform uDepthSource;
|
||||
fUniform uPrimDepth;
|
||||
fUniform uDeltaZ;
|
||||
};
|
||||
|
||||
class UDepthSource : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UDepthSource(GLuint _program) {
|
||||
LocateUniform(uDepthSource);
|
||||
LocateUniform(uPrimDepth);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uDepthSource.set(gDP.otherMode.depthSource, _force);
|
||||
if (gDP.otherMode.depthSource == G_ZS_PRIM)
|
||||
uPrimDepth.set(gDP.primDepth.z, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uDepthSource;
|
||||
fUniform uPrimDepth;
|
||||
};
|
||||
|
||||
class URenderTarget : public UniformGroup
|
||||
{
|
||||
public:
|
||||
URenderTarget(GLuint _program) {
|
||||
LocateUniform(uRenderTarget);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
int renderTarget = 0;
|
||||
if (isCurrentColorImageDepthImage()) {
|
||||
renderTarget = isDepthCompareEnabled() ? 2 : 1;
|
||||
}
|
||||
uRenderTarget.set(renderTarget, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uRenderTarget;
|
||||
};
|
||||
|
||||
class UClampMode : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UClampMode(GLuint _program) {
|
||||
LocateUniform(uClampMode);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
int clampMode = -1;
|
||||
switch (gfxContext.getClampMode())
|
||||
{
|
||||
case graphics::ClampMode::ClippingEnabled:
|
||||
clampMode = 0;
|
||||
break;
|
||||
case graphics::ClampMode::NoNearPlaneClipping:
|
||||
clampMode = 1;
|
||||
break;
|
||||
case graphics::ClampMode::NoClipping:
|
||||
clampMode = 2;
|
||||
break;
|
||||
}
|
||||
uClampMode.set(clampMode, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uClampMode;
|
||||
};
|
||||
|
||||
class UPolygonOffset : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UPolygonOffset(GLuint _program) {
|
||||
LocateUniform(uPolygonOffset);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
f32 offset = gfxContext.isEnabled(graphics::enable::POLYGON_OFFSET_FILL) ? 0.003f : 0.0f;
|
||||
uPolygonOffset.set(offset, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fUniform uPolygonOffset;
|
||||
};
|
||||
|
||||
class UScreenCoordsScale : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UScreenCoordsScale(GLuint _program) {
|
||||
LocateUniform(uScreenCoordsScale);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
f32 scaleX, scaleY;
|
||||
calcCoordsScales(frameBufferList().getCurrent(), scaleX, scaleY);
|
||||
uScreenCoordsScale.set(2.0f*scaleX, -2.0f*scaleY, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv2Uniform uScreenCoordsScale;
|
||||
};
|
||||
|
||||
class UColors : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UColors(GLuint _program) {
|
||||
LocateUniform(uFogColor);
|
||||
LocateUniform(uCenterColor);
|
||||
LocateUniform(uScaleColor);
|
||||
LocateUniform(uBlendColor);
|
||||
LocateUniform(uEnvColor);
|
||||
LocateUniform(uPrimColor);
|
||||
LocateUniform(uPrimLod);
|
||||
LocateUniform(uK4);
|
||||
LocateUniform(uK5);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uFogColor.set(&gDP.fogColor.r, _force);
|
||||
uCenterColor.set(&gDP.key.center.r, _force);
|
||||
uScaleColor.set(&gDP.key.scale.r, _force);
|
||||
uBlendColor.set(&gDP.blendColor.r, _force);
|
||||
uEnvColor.set(&gDP.envColor.r, _force);
|
||||
uPrimColor.set(&gDP.primColor.r, _force);
|
||||
uPrimLod.set(gDP.primColor.l, _force);
|
||||
uK4.set(_FIXED2FLOATCOLOR(gDP.convert.k4, 8 ), _force);
|
||||
uK5.set(_FIXED2FLOATCOLOR(gDP.convert.k5, 8 ), _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv4Uniform uFogColor;
|
||||
fv4Uniform uCenterColor;
|
||||
fv4Uniform uScaleColor;
|
||||
fv4Uniform uBlendColor;
|
||||
fv4Uniform uEnvColor;
|
||||
fv4Uniform uPrimColor;
|
||||
fUniform uPrimLod;
|
||||
fUniform uK4;
|
||||
fUniform uK5;
|
||||
};
|
||||
|
||||
class URectColor : public UniformGroup
|
||||
{
|
||||
public:
|
||||
URectColor(GLuint _program) {
|
||||
LocateUniform(uRectColor);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uRectColor.set(&gDP.rectColor.r, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv4Uniform uRectColor;
|
||||
};
|
||||
|
||||
class ULights : public UniformGroup
|
||||
{
|
||||
public:
|
||||
ULights(GLuint _program)
|
||||
{
|
||||
char buf[32];
|
||||
for (s32 i = 0; i < 8; ++i) {
|
||||
sprintf(buf, "uLightDirection[%d]", i);
|
||||
uLightDirection[i].loc = glGetUniformLocation(_program, buf);
|
||||
sprintf(buf, "uLightColor[%d]", i);
|
||||
uLightColor[i].loc = glGetUniformLocation(_program, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
for (u32 i = 0; i <= gSP.numLights; ++i) {
|
||||
uLightDirection[i].set(gSP.lights.xyz[i], _force);
|
||||
uLightColor[i].set(gSP.lights.rgb[i], _force);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
fv3Uniform uLightDirection[8];
|
||||
fv3Uniform uLightColor[8];
|
||||
};
|
||||
|
||||
|
||||
/*---------------CombinerProgramUniformFactoryCommon-------------*/
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addNoiseTex(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UNoiseTex(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addScreenSpaceTriangleInfo(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UScreenSpaceTriangleInfo(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addRasterInfo(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UScreenSpaceTriangleInfo(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addViewportInfo(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UViewportInfo(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addDepthTex(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UDepthTex(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addDepthScale(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UDepthScale(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addTextures(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UTextures(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addMSAATextures(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UMSAATextures(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addFrameBufferInfo(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UFrameBufferInfo(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addTextureFetchMode(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UTextureFetchMode(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addTexturePersp(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UTexturePersp(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addFog(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UFog(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addBlendMode1Cycle(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UBlendMode1Cycle(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addBlendMode2Cycle(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UBlendMode2Cycle(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addBlendCvg(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UBlendCvg(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addDitherMode(GLuint _program, UniformGroups &_uniforms, bool _usesNoise) const
|
||||
{
|
||||
_uniforms.emplace_back(new UDitherMode(_program, _usesNoise));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addScreenScale(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UScreenScale(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addAlphaTestInfo(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UAlphaTestInfo(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addZLutTexture(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UZLutTexture(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addDepthInfo(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UDepthInfo(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addDepthSource(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UDepthSource(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addRenderTarget(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new URenderTarget(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addClampMode(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UClampMode(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addPolygonOffset(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UPolygonOffset(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addScreenCoordsScale(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UScreenCoordsScale(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addColors(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UColors(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addRectColor(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new URectColor(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryCommon::_addLights(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new ULights(_program));
|
||||
}
|
||||
|
||||
CombinerProgramUniformFactoryCommon::CombinerProgramUniformFactoryCommon(const opengl::GLInfo & _glInfo)
|
||||
: CombinerProgramUniformFactory(_glInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
#pragma once
|
||||
#include "glsl_CombinerProgramUniformFactory.h"
|
||||
|
||||
namespace glsl {
|
||||
|
||||
/*---------------Uniform-------------*/
|
||||
|
||||
struct iUniform {
|
||||
GLint loc = -1;
|
||||
int val = -999;
|
||||
void set(int _val, bool _force) {
|
||||
if (loc >= 0 && (_force || val != _val)) {
|
||||
val = _val;
|
||||
glUniform1i(loc, _val);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct fUniform {
|
||||
GLint loc = -1;
|
||||
float val = -9999.9f;
|
||||
void set(float _val, bool _force) {
|
||||
if (loc >= 0 && (_force || val != _val)) {
|
||||
val = _val;
|
||||
glUniform1f(loc, _val);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct fv2Uniform {
|
||||
GLint loc = -1;
|
||||
float val1 = -9999.9f, val2 = -9999.9f;
|
||||
void set(float _val1, float _val2, bool _force) {
|
||||
if (loc >= 0 && (_force || val1 != _val1 || val2 != _val2)) {
|
||||
val1 = _val1;
|
||||
val2 = _val2;
|
||||
glUniform2f(loc, _val1, _val2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct fv3Uniform {
|
||||
GLint loc = -1;
|
||||
float val[3];
|
||||
void set(float * _pVal, bool _force) {
|
||||
const size_t szData = sizeof(float)* 3;
|
||||
if (loc >= 0 && (_force || memcmp(val, _pVal, szData) != 0)) {
|
||||
memcpy(val, _pVal, szData);
|
||||
glUniform3fv(loc, 1, _pVal);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct fv4Uniform {
|
||||
GLint loc = -1;
|
||||
float val[4];
|
||||
void set(float * _pVal, bool _force) {
|
||||
const size_t szData = sizeof(float)* 4;
|
||||
if (loc >= 0 && (_force || memcmp(val, _pVal, szData) != 0)) {
|
||||
memcpy(val, _pVal, szData);
|
||||
glUniform4fv(loc, 1, _pVal);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct iv2Uniform {
|
||||
GLint loc = -1;
|
||||
int val1 = -999, val2 = -999;
|
||||
void set(int _val1, int _val2, bool _force) {
|
||||
if (loc >= 0 && (_force || val1 != _val1 || val2 != _val2)) {
|
||||
val1 = _val1;
|
||||
val2 = _val2;
|
||||
glUniform2i(loc, _val1, _val2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct i4Uniform {
|
||||
GLint loc = -1;
|
||||
int val0 = -999, val1 = -999, val2 = -999, val3 = -999;
|
||||
void set(int _val0, int _val1, int _val2, int _val3, bool _force) {
|
||||
if (loc < 0)
|
||||
return;
|
||||
if (_force || _val0 != val0 || _val1 != val1 || _val2 != val2 || _val3 != val3) {
|
||||
val0 = _val0;
|
||||
val1 = _val1;
|
||||
val2 = _val2;
|
||||
val3 = _val3;
|
||||
glUniform4i(loc, val0, val1, val2, val3);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define LocateUniform(A) \
|
||||
A.loc = glGetUniformLocation(_program, #A);
|
||||
|
||||
class CombinerProgramUniformFactoryCommon : public CombinerProgramUniformFactory
|
||||
{
|
||||
public:
|
||||
CombinerProgramUniformFactoryCommon(const opengl::GLInfo & _glInfo);
|
||||
|
||||
private:
|
||||
void _addNoiseTex(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addScreenSpaceTriangleInfo(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addRasterInfo(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addViewportInfo(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addDepthTex(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addDepthScale(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addTextures(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addMSAATextures(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addFrameBufferInfo(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addTextureFetchMode(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addTexturePersp(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addFog(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addBlendMode1Cycle(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addBlendMode2Cycle(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addBlendCvg(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addDitherMode(GLuint _program, UniformGroups &_uniforms, bool _usesNoise) const override;
|
||||
|
||||
void _addScreenScale(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addAlphaTestInfo(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addZLutTexture(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addDepthInfo(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addDepthSource(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addRenderTarget(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addClampMode(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addPolygonOffset(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addScreenCoordsScale(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addColors(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addRectColor(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
void _addLights(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,433 @@
|
|||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <Config.h>
|
||||
#include "glsl_CombinerProgramUniformFactoryFast.h"
|
||||
#include <Graphics/Parameters.h>
|
||||
#include <Graphics/Context.h>
|
||||
|
||||
#include <Textures.h>
|
||||
#include <NoiseTexture.h>
|
||||
#include <FrameBuffer.h>
|
||||
#include <DisplayWindow.h>
|
||||
#include <Debugger.h>
|
||||
#include <GBI.h>
|
||||
#include <RSP.h>
|
||||
#include <gSP.h>
|
||||
#include <gDP.h>
|
||||
#include <VI.h>
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
namespace glsl {
|
||||
|
||||
class URasterInfoFast : public UniformGroup {
|
||||
public:
|
||||
URasterInfoFast(GLuint _program) {
|
||||
LocateUniform(uVertexOffset);
|
||||
LocateUniform(uTexCoordOffset[0]);
|
||||
LocateUniform(uTexCoordOffset[1]);
|
||||
LocateUniform(uUseTexCoordBounds);
|
||||
LocateUniform(uTexCoordBounds0);
|
||||
LocateUniform(uTexCoordBounds1);
|
||||
}
|
||||
|
||||
void update(bool _force) override {
|
||||
const bool isNativeRes = config.frameBufferEmulation.nativeResFactor == 1 && config.video.multisampling == 0;
|
||||
const bool isTexRect = dwnd().getDrawer().getDrawingState() == DrawingState::TexRect;
|
||||
const bool useTexCoordBounds = isTexRect && !isNativeRes && config.graphics2D.enableTexCoordBounds;
|
||||
/* At rasterization stage, the N64 places samples on the top left of the fragment while OpenGL */
|
||||
/* places them in the fragment center. As a result, a normal approach results in shifted texture */
|
||||
/* coordinates. In native resolution, this difference can be negated by shifting vertices by 0.5. */
|
||||
/* In higher resolutions, there are more samples than the game intends, so shifting is not very */
|
||||
/* effective. Still, an heuristic is applied to render texture rectangles as correctly as possible */
|
||||
/* in higher resolutions too. See issue #2324 for details. */
|
||||
const float vertexOffset = isNativeRes ? 0.5f : 0.0f;
|
||||
float texCoordOffset[2][2] = { 0.0f, 0.0f };
|
||||
if (isTexRect && !isNativeRes) {
|
||||
float scale[2] = { 0.0f, 0.0f };
|
||||
if (config.graphics2D.enableNativeResTexrects != 0 && gDP.otherMode.textureFilter != G_TF_POINT) {
|
||||
scale[0] = scale[1] = 1.0f;
|
||||
} else {
|
||||
scale[0] = scale[1] = static_cast<float>(config.frameBufferEmulation.nativeResFactor);
|
||||
}
|
||||
|
||||
for (int t = 0; t < 2; t++) {
|
||||
const CachedTexture* _pTexture = textureCache().current[t];
|
||||
if (_pTexture != nullptr) {
|
||||
if (config.frameBufferEmulation.nativeResFactor != 0) {
|
||||
texCoordOffset[t][0] = (gDP.lastTexRectInfo.dsdx >= 0.0f ? -0.5f / scale[0] : -1.0f + 0.5f / scale[0]) * gDP.lastTexRectInfo.dsdx * _pTexture->hdRatioS;
|
||||
texCoordOffset[t][1] = (gDP.lastTexRectInfo.dtdy >= 0.0f ? -0.5f / scale[1] : -1.0f + 0.5f / scale[1]) * gDP.lastTexRectInfo.dtdy * _pTexture->hdRatioT;
|
||||
} else {
|
||||
texCoordOffset[t][0] = (gDP.lastTexRectInfo.dsdx >= 0.0f ? 0.0f : -1.0f) * gDP.lastTexRectInfo.dsdx * _pTexture->hdRatioS;
|
||||
texCoordOffset[t][1] = (gDP.lastTexRectInfo.dtdy >= 0.0f ? 0.0f : -1.0f) * gDP.lastTexRectInfo.dtdy * _pTexture->hdRatioT;
|
||||
if (gDP.otherMode.textureFilter != G_TF_POINT && gDP.otherMode.cycleType != G_CYC_COPY) {
|
||||
texCoordOffset[t][0] -= 0.5f;
|
||||
texCoordOffset[t][1] -= 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Hack for framebuffer textures. See #519 and #2112 */
|
||||
if ((config.generalEmulation.hacks & hack_fbTextureOffset) != 0) {
|
||||
for (int t = 0; t < 2; t++) {
|
||||
const CachedTexture* _pTexture = textureCache().current[t];
|
||||
if (_pTexture != nullptr) {
|
||||
if (gDP.otherMode.textureFilter != G_TF_POINT && _pTexture->frameBufferTexture != CachedTexture::fbNone) {
|
||||
texCoordOffset[t][0] -= 1.0f;
|
||||
texCoordOffset[t][1] -= 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
float tcbounds[2][4] = {};
|
||||
if (useTexCoordBounds) {
|
||||
f32 uls, lrs, ult, lrt, S, T, shiftScaleS, shiftScaleT;
|
||||
s16 shiftedS, shiftedT;
|
||||
u32 shifts, shiftt;
|
||||
for (int t = 0; t < 2; t++) {
|
||||
const CachedTexture * _pTexture = textureCache().current[t];
|
||||
const gDPTile * _pTile = gSP.textureTile[t];
|
||||
if (_pTexture != nullptr && _pTile != nullptr){
|
||||
if (_pTile->shifts > 10) {
|
||||
shifts = 16 - _pTile->shifts;
|
||||
shiftedS = static_cast<s16>(gDP.lastTexRectInfo.s << shifts);
|
||||
shiftScaleS = static_cast<f32>(1 << shifts);
|
||||
} else {
|
||||
shifts = _pTile->shifts;
|
||||
shiftedS = static_cast<s16>(gDP.lastTexRectInfo.s >> shifts);
|
||||
shiftScaleS = 1.0f / static_cast<f32>(1 << shifts);
|
||||
}
|
||||
if (_pTile->shiftt > 10) {
|
||||
shiftt = 16 - _pTile->shiftt;
|
||||
shiftedT = static_cast<s16>(gDP.lastTexRectInfo.t << shiftt);
|
||||
shiftScaleT = static_cast<f32>(1 << shiftt);
|
||||
} else {
|
||||
shiftt = _pTile->shiftt;
|
||||
shiftedT = static_cast<s16>(gDP.lastTexRectInfo.t >> shiftt);
|
||||
shiftScaleT = 1.0f / static_cast<f32>(1 << shiftt);
|
||||
}
|
||||
|
||||
S = _FIXED2FLOAT(shiftedS, 5);
|
||||
T = _FIXED2FLOAT(shiftedT, 5);
|
||||
uls = S + (ceilf(gDP.lastTexRectInfo.ulx) - gDP.lastTexRectInfo.ulx) * gDP.lastTexRectInfo.dsdx * shiftScaleS;
|
||||
lrs = S + (ceilf(gDP.lastTexRectInfo.lrx) - gDP.lastTexRectInfo.ulx - 1.0f) * gDP.lastTexRectInfo.dsdx * shiftScaleS;
|
||||
ult = T + (ceilf(gDP.lastTexRectInfo.uly) - gDP.lastTexRectInfo.uly) * gDP.lastTexRectInfo.dtdy * shiftScaleT;
|
||||
lrt = T + (ceilf(gDP.lastTexRectInfo.lry) - gDP.lastTexRectInfo.uly - 1.0f) * gDP.lastTexRectInfo.dtdy * shiftScaleT;
|
||||
|
||||
tcbounds[t][0] = (fmin(uls, lrs) - _pTile->fuls) * _pTexture->hdRatioS;
|
||||
tcbounds[t][1] = (fmin(ult, lrt) - _pTile->fult) * _pTexture->hdRatioT;
|
||||
tcbounds[t][2] = (fmax(uls, lrs) - _pTile->fuls) * _pTexture->hdRatioS;
|
||||
tcbounds[t][3] = (fmax(ult, lrt) - _pTile->fult) * _pTexture->hdRatioT;
|
||||
if (_pTexture->frameBufferTexture != CachedTexture::fbNone) {
|
||||
tcbounds[t][0] += _pTexture->offsetS * _pTexture->hdRatioS;
|
||||
tcbounds[t][1] += _pTexture->offsetT * _pTexture->hdRatioT;
|
||||
tcbounds[t][2] += _pTexture->offsetS * _pTexture->hdRatioS;
|
||||
tcbounds[t][3] += _pTexture->offsetT * _pTexture->hdRatioT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uVertexOffset.set(vertexOffset, vertexOffset, _force);
|
||||
uTexCoordOffset[0].set(texCoordOffset[0][0], texCoordOffset[0][1], _force);
|
||||
uTexCoordOffset[1].set(texCoordOffset[1][0], texCoordOffset[1][1], _force);
|
||||
uUseTexCoordBounds.set(useTexCoordBounds ? 1 : 0, _force);
|
||||
uTexCoordBounds0.set(tcbounds[0], _force);
|
||||
uTexCoordBounds1.set(tcbounds[1], _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv2Uniform uVertexOffset;
|
||||
fv2Uniform uTexCoordOffset[2];
|
||||
iUniform uUseTexCoordBounds;
|
||||
fv4Uniform uTexCoordBounds0;
|
||||
fv4Uniform uTexCoordBounds1;
|
||||
};
|
||||
|
||||
class UMipmap1 : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UMipmap1(GLuint _program) {
|
||||
LocateUniform(uMinLod);
|
||||
LocateUniform(uMaxTile);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
uMinLod.set(gDP.primColor.m, _force);
|
||||
uMaxTile.set(gSP.texture.level, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fUniform uMinLod;
|
||||
iUniform uMaxTile;
|
||||
};
|
||||
|
||||
class UMipmap2 : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UMipmap2(GLuint _program) {
|
||||
LocateUniform(uEnableLod);
|
||||
LocateUniform(uTextureDetail);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
const int uCalcLOD = (gDP.otherMode.textureLOD == G_TL_LOD) ? 1 : 0;
|
||||
uEnableLod.set(uCalcLOD, _force);
|
||||
uTextureDetail.set(gDP.otherMode.textureDetail, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
iUniform uEnableLod;
|
||||
iUniform uTextureDetail;
|
||||
};
|
||||
|
||||
class UTextureSizeFast : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UTextureSizeFast(GLuint _program, bool _useT0, bool _useT1)
|
||||
: m_useT0(_useT0)
|
||||
, m_useT1(_useT1)
|
||||
{
|
||||
LocateUniform(uTextureSize[0]);
|
||||
LocateUniform(uTextureSize[1]);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
TextureCache & cache = textureCache();
|
||||
if (m_useT0 && cache.current[0] != NULL)
|
||||
uTextureSize[0].set((float)cache.current[0]->width, (float)cache.current[0]->height, _force);
|
||||
if (m_useT1 && cache.current[1] != NULL)
|
||||
uTextureSize[1].set((float)cache.current[1]->width, (float)cache.current[1]->height, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
fv2Uniform uTextureSize[2];
|
||||
bool m_useT0;
|
||||
bool m_useT1;
|
||||
};
|
||||
|
||||
class UTextureParamsFast : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UTextureParamsFast(GLuint _program, bool _useT0, bool _useT1)
|
||||
{
|
||||
m_useTile[0] = _useT0;
|
||||
m_useTile[1] = _useT1;
|
||||
LocateUniform(uTexOffset[0]);
|
||||
LocateUniform(uTexOffset[1]);
|
||||
LocateUniform(uCacheShiftScale[0]);
|
||||
LocateUniform(uCacheShiftScale[1]);
|
||||
LocateUniform(uCacheScale[0]);
|
||||
LocateUniform(uCacheScale[1]);
|
||||
LocateUniform(uCacheOffset[0]);
|
||||
LocateUniform(uCacheOffset[1]);
|
||||
LocateUniform(uTexScale);
|
||||
LocateUniform(uCacheFrameBuffer);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
int nFB[2] = { 0, 0 };
|
||||
TextureCache & cache = textureCache();
|
||||
for (u32 t = 0; t < 2; ++t) {
|
||||
if (!m_useTile[t])
|
||||
continue;
|
||||
|
||||
gDPTile * pTile = gSP.textureTile[t];
|
||||
if (pTile != nullptr) {
|
||||
if (pTile->textureMode == TEXTUREMODE_BGIMAGE || pTile->textureMode == TEXTUREMODE_FRAMEBUFFER_BG)
|
||||
uTexOffset[t].set(0.0f, 0.0f, _force);
|
||||
else {
|
||||
float fuls = pTile->fuls;
|
||||
float fult = pTile->fult;
|
||||
if (pTile->frameBufferAddress > 0) {
|
||||
FrameBuffer * pBuffer = frameBufferList().getBuffer(pTile->frameBufferAddress);
|
||||
if (pBuffer != nullptr) {
|
||||
if (pTile->masks > 0 && pTile->clamps == 0)
|
||||
fuls = float(pTile->uls % (1 << pTile->masks));
|
||||
if (pTile->maskt > 0 && pTile->clampt == 0)
|
||||
fult = float(pTile->ult % (1 << pTile->maskt));
|
||||
} else {
|
||||
pTile->frameBufferAddress = 0;
|
||||
}
|
||||
}
|
||||
uTexOffset[t].set(fuls, fult, _force);
|
||||
}
|
||||
}
|
||||
|
||||
CachedTexture *_pTexture = cache.current[t];
|
||||
if (_pTexture != nullptr) {
|
||||
f32 shiftScaleS = 1.0f;
|
||||
f32 shiftScaleT = 1.0f;
|
||||
getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT);
|
||||
uCacheShiftScale[t].set(shiftScaleS, shiftScaleT, _force);
|
||||
uCacheScale[t].set(_pTexture->scaleS, _pTexture->scaleT, _force);
|
||||
uCacheOffset[t].set(_pTexture->offsetS, _pTexture->offsetT, _force);
|
||||
nFB[t] = _pTexture->frameBufferTexture;
|
||||
}
|
||||
}
|
||||
|
||||
uCacheFrameBuffer.set(nFB[0], nFB[1], _force);
|
||||
uTexScale.set(gSP.texture.scales, gSP.texture.scalet, _force);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_useTile[2];
|
||||
fv2Uniform uTexOffset[2];
|
||||
fv2Uniform uCacheShiftScale[2];
|
||||
fv2Uniform uCacheScale[2];
|
||||
fv2Uniform uCacheOffset[2];
|
||||
fv2Uniform uTexScale;
|
||||
iv2Uniform uCacheFrameBuffer;
|
||||
};
|
||||
|
||||
class UClampWrapMirrorTex : public UniformGroup
|
||||
{
|
||||
public:
|
||||
UClampWrapMirrorTex(GLuint _program, bool _useT0, bool _useT1)
|
||||
{
|
||||
m_useTile[0] = _useT0;
|
||||
m_useTile[1] = _useT1;
|
||||
LocateUniform(uTexClamp0);
|
||||
LocateUniform(uTexClamp1);
|
||||
LocateUniform(uTexWrap0);
|
||||
LocateUniform(uTexWrap1);
|
||||
LocateUniform(uTexMirror0);
|
||||
LocateUniform(uTexMirror1);
|
||||
LocateUniform(uTexScale0);
|
||||
LocateUniform(uTexScale1);
|
||||
}
|
||||
|
||||
void update(bool _force) override
|
||||
{
|
||||
std::array<f32, 4> aTexClamp[2] = { { -10000.0f, -10000.0f, 10000.0f, 10000.0f },
|
||||
{ -10000.0f, -10000.0f, 10000.0f, 10000.0f } };
|
||||
std::array<f32, 2> aTexWrap[2] = { { 10000.0f, 10000.0f }, { 10000.0f, 10000.0f } };
|
||||
std::array<f32, 2> aTexMirror[2] = { { 0.0f, 0.0f}, { 0.0f, 0.0f } };
|
||||
std::array<f32, 2> aTexScale[2] = { { 1.0f, 1.0f },{ 1.0f, 1.0f } };
|
||||
TextureCache & cache = textureCache();
|
||||
const bool replaceTex1ByTex0 = needReplaceTex1ByTex0();
|
||||
for (u32 t = 0; t < 2; ++t) {
|
||||
if (!m_useTile[t])
|
||||
continue;
|
||||
|
||||
const u32 tile = replaceTex1ByTex0 ? 0 : t;
|
||||
const gDPTile * pTile = gSP.textureTile[tile];
|
||||
CachedTexture * pTexture = cache.current[tile];
|
||||
if (pTile == nullptr || pTexture == nullptr)
|
||||
continue;
|
||||
|
||||
if (gDP.otherMode.cycleType != G_CYC_COPY) {
|
||||
if (pTexture->clampS) {
|
||||
aTexClamp[t][0] = 0.0f; // S lower bound
|
||||
if (pTexture->frameBufferTexture != CachedTexture::fbNone ||
|
||||
pTile->textureMode == TEXTUREMODE_BGIMAGE)
|
||||
aTexClamp[t][2] = 1.0f;
|
||||
else {
|
||||
u32 tileWidth = ((pTile->lrs - pTile->uls) & 0x03FF) + 1;
|
||||
if (pTile->size > pTexture->size)
|
||||
tileWidth <<= pTile->size - pTexture->size;
|
||||
// aTexClamp[t][2] = f32(tileWidth) / (pTexture->mirrorS ? f32(pTexture->width) : f32(pTexture->clampWidth)); // S upper bound
|
||||
aTexClamp[t][2] = f32(tileWidth) / f32(pTexture->width); // S upper bound
|
||||
}
|
||||
}
|
||||
if (pTexture->clampT) {
|
||||
aTexClamp[t][1] = 0.0f; // T lower bound
|
||||
if (pTexture->frameBufferTexture != CachedTexture::fbNone ||
|
||||
pTile->textureMode == TEXTUREMODE_BGIMAGE)
|
||||
aTexClamp[t][3] = 1.0f;
|
||||
else {
|
||||
const u32 tileHeight = ((pTile->lrt - pTile->ult) & 0x03FF) + 1;
|
||||
// aTexClamp[t][3] = f32(tileHeight) / (pTexture->mirrorT ? f32(pTexture->height) : f32(pTexture->clampHeight)); // T upper bound
|
||||
aTexClamp[t][3] = f32(tileHeight) / f32(pTexture->height); // T upper bound
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pTexture->maskS) {
|
||||
const f32 wrapWidth = static_cast<f32>(1 << pTile->originalMaskS);
|
||||
const f32 pow2Width = static_cast<f32>(pow2(pTexture->width));
|
||||
aTexWrap[t][0] = wrapWidth / pow2Width;
|
||||
aTexScale[t][0] = pow2Width / f32(pTexture->width);
|
||||
}
|
||||
if (pTexture->maskT) {
|
||||
const f32 wrapHeight = static_cast<f32>(1 << pTile->originalMaskT);
|
||||
const f32 pow2Height = static_cast<f32>(pow2(pTexture->height));
|
||||
aTexWrap[t][1] = wrapHeight / pow2Height;
|
||||
aTexScale[t][1] = pow2Height / f32(pTexture->height);
|
||||
}
|
||||
if (pTexture->mirrorS) {
|
||||
aTexMirror[t][0] = 1.0f;
|
||||
aTexWrap[t][0] *= 2.0f;
|
||||
}
|
||||
if (pTexture->mirrorT) {
|
||||
aTexMirror[t][1] = 1.0f;
|
||||
aTexWrap[t][1] *= 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
uTexClamp0.set(aTexClamp[0].data(), _force);
|
||||
uTexClamp1.set(aTexClamp[1].data(), _force);
|
||||
uTexWrap0.set(aTexWrap[0][0], aTexWrap[0][1], _force);
|
||||
uTexWrap1.set(aTexWrap[1][0], aTexWrap[1][1], _force);
|
||||
uTexMirror0.set(aTexMirror[0][0], aTexMirror[0][1], _force);
|
||||
uTexMirror1.set(aTexMirror[1][0], aTexMirror[1][1], _force);
|
||||
uTexScale0.set(aTexScale[0][0], aTexScale[0][1], _force);
|
||||
uTexScale1.set(aTexScale[1][0], aTexScale[1][1], _force);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_useTile[2];
|
||||
fv4Uniform uTexClamp0;
|
||||
fv4Uniform uTexClamp1;
|
||||
fv2Uniform uTexWrap0;
|
||||
fv2Uniform uTexWrap1;
|
||||
fv2Uniform uTexMirror0;
|
||||
fv2Uniform uTexMirror1;
|
||||
fv2Uniform uTexScale0;
|
||||
fv2Uniform uTexScale1;
|
||||
};
|
||||
|
||||
/*---------------CombinerProgramUniformFactoryCommon-------------*/
|
||||
|
||||
void CombinerProgramUniformFactoryFast::_addRasterInfo(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new URasterInfoFast(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryFast::_addMipmap(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UMipmap1(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryFast::_addMipmap2(GLuint _program, UniformGroups &_uniforms) const
|
||||
{
|
||||
_uniforms.emplace_back(new UMipmap2(_program));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryFast::_addTextureSize(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const
|
||||
{
|
||||
_uniforms.emplace_back(new UTextureSizeFast(_program, _usesTile0, _usesTile1));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryFast::_addTextureParams(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const
|
||||
{
|
||||
_uniforms.emplace_back(new UTextureParamsFast(_program, _usesTile0, _usesTile1));
|
||||
}
|
||||
|
||||
void CombinerProgramUniformFactoryFast::_addClampWrapMirrorEngine(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const
|
||||
{
|
||||
_uniforms.emplace_back(new UClampWrapMirrorTex(_program, _usesTile0, _usesTile1));
|
||||
}
|
||||
|
||||
CombinerProgramUniformFactoryFast::CombinerProgramUniformFactoryFast(const opengl::GLInfo & _glInfo)
|
||||
: CombinerProgramUniformFactoryCommon(_glInfo)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
#include <Graphics/OpenGLContext/opengl_GLInfo.h>
|
||||
#include "glsl_CombinerProgramImpl.h"
|
||||
#include "glsl_CombinerProgramUniformFactoryCommon.h"
|
||||
|
||||
namespace glsl {
|
||||
class CombinerProgramUniformFactoryFast : public CombinerProgramUniformFactoryCommon {
|
||||
|
||||
public:
|
||||
CombinerProgramUniformFactoryFast(const opengl::GLInfo & _glInfo);
|
||||
private:
|
||||
|
||||
virtual void _addRasterInfo(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
virtual void _addMipmap(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
virtual void _addMipmap2(GLuint _program, UniformGroups &_uniforms) const override;
|
||||
|
||||
virtual void _addTextureSize(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const override;
|
||||
|
||||
virtual void _addTextureParams(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const override;
|
||||
|
||||
virtual void _addClampWrapMirrorEngine(GLuint _program, UniformGroups &_uniforms, bool _usesTile0, bool _usesTile1) const override;
|
||||
};
|
||||
}
|
||||
|
|
@ -14,10 +14,12 @@
|
|||
#include <Combiner.h>
|
||||
#include <DisplayLoadProgress.h>
|
||||
#include <osal_files.h>
|
||||
#include <Config.h>
|
||||
#include "glsl_Utils.h"
|
||||
#include "glsl_ShaderStorage.h"
|
||||
#include "glsl_CombinerProgramImpl.h"
|
||||
#include "glsl_CombinerProgramUniformFactory.h"
|
||||
#include "glsl_CombinerProgramUniformFactoryAccurate.h"
|
||||
#include "glsl_CombinerProgramUniformFactoryFast.h"
|
||||
|
||||
using namespace glsl;
|
||||
|
||||
|
@ -203,7 +205,7 @@ bool ShaderStorage::saveShadersStorage(const graphics::Combiners & _combiners) c
|
|||
static
|
||||
CombinerProgramImpl * _readCombinerProgramFromStream(std::istream & _is,
|
||||
CombinerKey& _cmbKey,
|
||||
CombinerProgramUniformFactory & _uniformFactory,
|
||||
std::unique_ptr<CombinerProgramUniformFactory> & _uniformFactory,
|
||||
opengl::CachedUseProgram * _useProgram)
|
||||
{
|
||||
int inputs;
|
||||
|
@ -226,7 +228,7 @@ CombinerProgramImpl * _readCombinerProgramFromStream(std::istream & _is,
|
|||
}
|
||||
|
||||
UniformGroups uniforms;
|
||||
_uniformFactory.buildUniforms(program, cmbInputs, _cmbKey, uniforms);
|
||||
_uniformFactory->buildUniforms(program, cmbInputs, _cmbKey, uniforms);
|
||||
|
||||
return new CombinerProgramImpl(_cmbKey, program, _useProgram, cmbInputs, std::move(uniforms));
|
||||
}
|
||||
|
@ -336,7 +338,14 @@ bool ShaderStorage::loadShadersStorage(graphics::Combiners & _combiners)
|
|||
return _loadFromCombinerKeys(_combiners);
|
||||
|
||||
displayLoadProgress(L"LOAD COMBINER SHADERS %.1f%%", 0.0f);
|
||||
CombinerProgramUniformFactory uniformFactory(m_glinfo);
|
||||
|
||||
std::unique_ptr<CombinerProgramUniformFactory> uniformFactory;
|
||||
|
||||
if (config.generalEmulation.enableInaccurateTextureCoordinates) {
|
||||
uniformFactory = std::make_unique<CombinerProgramUniformFactoryFast>(m_glinfo);
|
||||
} else {
|
||||
uniformFactory = std::make_unique<CombinerProgramUniformFactoryAccurate>(m_glinfo);
|
||||
}
|
||||
|
||||
fin.read((char*)&len, sizeof(len));
|
||||
const f32 percent = len / 100.0f;
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace glsl {
|
|||
bool _saveCombinerKeys(const graphics::Combiners & _combiners) const;
|
||||
bool _loadFromCombinerKeys(graphics::Combiners & _combiners);
|
||||
|
||||
const u32 m_formatVersion = 0x37U;
|
||||
const u32 m_formatVersion = 0x38U;
|
||||
const u32 m_keysFormatVersion = 0x05;
|
||||
const opengl::GLInfo & m_glinfo;
|
||||
opengl::CachedUseProgram * m_useProgram;
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
#endif
|
||||
#include "opengl_ColorBufferReaderWithReadPixels.h"
|
||||
#include "opengl_Utils.h"
|
||||
#include "GLSL/glsl_CombinerProgramBuilder.h"
|
||||
#include "GLSL/glsl_CombinerProgramBuilderAccurate.h"
|
||||
#include "GLSL/glsl_CombinerProgramBuilderFast.h"
|
||||
#include "GLSL/glsl_SpecialShadersFactory.h"
|
||||
#include "GLSL/glsl_ShaderStorage.h"
|
||||
|
||||
|
@ -408,7 +409,13 @@ void ContextImpl::resetCombinerProgramBuilder()
|
|||
{
|
||||
if (!isCombinerProgramBuilderObsolete())
|
||||
return;
|
||||
m_combinerProgramBuilder.reset(new glsl::CombinerProgramBuilder(m_glInfo, m_cachedFunctions->getCachedUseProgram()));
|
||||
|
||||
if (config.generalEmulation.enableInaccurateTextureCoordinates) {
|
||||
m_combinerProgramBuilder = std::make_unique<glsl::CombinerProgramBuilderFast>(m_glInfo, m_cachedFunctions->getCachedUseProgram());
|
||||
} else {
|
||||
m_combinerProgramBuilder = std::make_unique<glsl::CombinerProgramBuilderAccurate>(m_glInfo, m_cachedFunctions->getCachedUseProgram());
|
||||
}
|
||||
|
||||
m_specialShadersFactory.reset(new glsl::SpecialShadersFactory(m_glInfo,
|
||||
m_cachedFunctions->getCachedUseProgram(),
|
||||
m_combinerProgramBuilder->getVertexShaderHeader(),
|
||||
|
|
|
@ -1277,15 +1277,59 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
|
|||
|
||||
for (u32 t = 0; t < 2; ++t) {
|
||||
if (pCurrentCombiner->usesTile(t) && cache.current[t] && gSP.textureTile[t]) {
|
||||
const f32 uls = _FIXED2FLOAT(_params.s, 5);
|
||||
const f32 lrs = uls + offsetX;
|
||||
const f32 ult = _FIXED2FLOAT(_params.t, 5);
|
||||
const f32 lrt = ult + offsetY;
|
||||
|
||||
texST[t].s0 = uls;
|
||||
texST[t].s1 = lrs;
|
||||
texST[t].t0 = ult;
|
||||
texST[t].t1 = lrt;
|
||||
if (config.generalEmulation.enableInaccurateTextureCoordinates) {
|
||||
f32 shiftScaleS = 1.0f;
|
||||
f32 shiftScaleT = 1.0f;
|
||||
|
||||
s16 S = _params.s;
|
||||
if (gSP.textureTile[t]->shifts > 10) {
|
||||
const u32 shifts = 16 - gSP.textureTile[t]->shifts;
|
||||
S = static_cast<s16>(S << shifts);
|
||||
shiftScaleS = static_cast<f32>(1 << shifts);
|
||||
} else if (gSP.textureTile[t]->shifts > 0) {
|
||||
const u32 shifts = gSP.textureTile[t]->shifts;
|
||||
S = static_cast<s16>(S >> shifts);
|
||||
shiftScaleS /= static_cast<f32>(1 << shifts);
|
||||
}
|
||||
const f32 uls = _FIXED2FLOAT(S, 5);
|
||||
const f32 lrs = uls + offsetX * shiftScaleS;
|
||||
|
||||
s16 T = _params.t;
|
||||
if (gSP.textureTile[t]->shiftt > 10) {
|
||||
const u32 shiftt = 16 - gSP.textureTile[t]->shiftt;
|
||||
T = static_cast<s16>(T << shiftt);
|
||||
shiftScaleT = static_cast<f32>(1 << shiftt);
|
||||
} else if (gSP.textureTile[t]->shiftt > 0) {
|
||||
const u32 shiftt = gSP.textureTile[t]->shiftt;
|
||||
T = static_cast<s16>(T >> shiftt);
|
||||
shiftScaleT /= static_cast<f32>(1 << shiftt);
|
||||
}
|
||||
const f32 ult = _FIXED2FLOAT(T, 5);
|
||||
const f32 lrt = ult + offsetY * shiftScaleT;
|
||||
|
||||
texST[t].s0 = uls - gSP.textureTile[t]->fuls;
|
||||
texST[t].s1 = lrs - gSP.textureTile[t]->fuls;
|
||||
texST[t].t0 = ult - gSP.textureTile[t]->fult;
|
||||
texST[t].t1 = lrt - gSP.textureTile[t]->fult;
|
||||
|
||||
if (cache.current[t]->frameBufferTexture != CachedTexture::fbNone) {
|
||||
texST[t].s0 = cache.current[t]->offsetS + texST[t].s0;
|
||||
texST[t].t0 = cache.current[t]->offsetT + texST[t].t0;
|
||||
texST[t].s1 = cache.current[t]->offsetS + texST[t].s1;
|
||||
texST[t].t1 = cache.current[t]->offsetT + texST[t].t1;
|
||||
}
|
||||
} else {
|
||||
const f32 uls = _FIXED2FLOAT(_params.s, 5);
|
||||
const f32 lrs = uls + offsetX;
|
||||
const f32 ult = _FIXED2FLOAT(_params.t, 5);
|
||||
const f32 lrt = ult + offsetY;
|
||||
|
||||
texST[t].s0 = uls;
|
||||
texST[t].s1 = lrs;
|
||||
texST[t].t0 = ult;
|
||||
texST[t].t1 = lrt;
|
||||
}
|
||||
|
||||
if (cache.current[t]->frameBufferTexture != CachedTexture::fbMultiSample) {
|
||||
Context::TexParameters texParams;
|
||||
|
@ -1310,6 +1354,13 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
|
|||
gfxContext.setTextureParameters(texParams);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.generalEmulation.enableInaccurateTextureCoordinates) {
|
||||
texST[t].s0 *= cache.current[t]->scaleS;
|
||||
texST[t].t0 *= cache.current[t]->scaleT;
|
||||
texST[t].s1 *= cache.current[t]->scaleS;
|
||||
texST[t].t1 *= cache.current[t]->scaleT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
270
src/Textures.cpp
270
src/Textures.cpp
|
@ -1100,7 +1100,206 @@ void doubleTexture(T* pTex, u32 width, u32 height)
|
|||
}
|
||||
}
|
||||
|
||||
void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
||||
void TextureCache::_loadFast(u32 _tile, CachedTexture *_pTexture)
|
||||
{
|
||||
u64 ricecrc = 0;
|
||||
if (_loadHiresTexture(_tile, _pTexture, ricecrc))
|
||||
return;
|
||||
|
||||
s32 mipLevel = 0;
|
||||
bool force32bitFormat = false;
|
||||
_pTexture->max_level = 0;
|
||||
|
||||
if (config.generalEmulation.enableLOD != 0 && gSP.texture.level > 1) {
|
||||
if (_tile == 0) {
|
||||
_pTexture->max_level = 0;
|
||||
} else {
|
||||
_pTexture->max_level = static_cast<u8>(gSP.texture.level - 1);
|
||||
const u16 dim = std::max(_pTexture->width, _pTexture->height);
|
||||
while (dim < static_cast<u16>(1 << _pTexture->max_level))
|
||||
--_pTexture->max_level;
|
||||
|
||||
auto texFormat = gDP.tiles[gSP.texture.tile + 1].format;
|
||||
auto texSize = gDP.tiles[gSP.texture.tile + 1].size;
|
||||
u32 tileMipLevel = gSP.texture.tile + 2;
|
||||
while (!force32bitFormat && (tileMipLevel < gSP.texture.tile + gSP.texture.level)) {
|
||||
gDPTile const& mipTile = gDP.tiles[tileMipLevel++];
|
||||
force32bitFormat = texFormat != mipTile.format || texSize != mipTile.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 sizeShift = 1;
|
||||
{
|
||||
const TextureLoadParameters & loadParams =
|
||||
ImageFormat::get().tlp[gDP.otherMode.textureLUT][_pTexture->size][_pTexture->format];
|
||||
if (force32bitFormat || loadParams.autoFormat == internalcolorFormat::RGBA8)
|
||||
sizeShift = 2;
|
||||
}
|
||||
_pTexture->textureBytes = (_pTexture->width * _pTexture->height) << sizeShift;
|
||||
|
||||
unsigned int totalTexSize = std::max(static_cast<u32>(_pTexture->textureBytes/sizeof(u32) + 8), MIPMAP_TILE_WIDTH)
|
||||
* (_pTexture->max_level + 1);
|
||||
|
||||
if (m_tempTextureHolder.size() < totalTexSize) {
|
||||
m_tempTextureHolder.resize(totalTexSize);
|
||||
}
|
||||
|
||||
GetTexelFunc GetTexel;
|
||||
InternalColorFormatParam glInternalFormat;
|
||||
DatatypeParam glType;
|
||||
|
||||
auto getLoadParams = [&](u16 _format, u16 _size)
|
||||
{
|
||||
const TextureLoadParameters & loadParams =
|
||||
ImageFormat::get().tlp[gDP.otherMode.textureLUT][_size][_format];
|
||||
if (force32bitFormat || loadParams.autoFormat == internalcolorFormat::RGBA8) {
|
||||
GetTexel = loadParams.Get32;
|
||||
glInternalFormat = loadParams.glInternalFormat32;
|
||||
glType = loadParams.glType32;
|
||||
}
|
||||
else {
|
||||
GetTexel = loadParams.Get16;
|
||||
glInternalFormat = loadParams.glInternalFormat16;
|
||||
glType = loadParams.glType16;
|
||||
}
|
||||
};
|
||||
|
||||
CachedTexture tmptex = *_pTexture;
|
||||
u16 line = tmptex.line;
|
||||
|
||||
while (true) {
|
||||
getLoadParams(tmptex.format, tmptex.size);
|
||||
{
|
||||
const u32 tileMipLevel = gSP.texture.tile + mipLevel + 1;
|
||||
gDPTile & mipTile = gDP.tiles[tileMipLevel];
|
||||
if (tmptex.max_level > 1 &&
|
||||
tmptex.width == (mipTile.lrs - mipTile.uls + 1) * 2 &&
|
||||
tmptex.height == (mipTile.lrt - mipTile.ult + 1) * 2)
|
||||
{
|
||||
// Special case for Southern Swamp grass texture, Zelda MM. See #2315
|
||||
const u16 texWidth = tmptex.width;
|
||||
const u16 texHeight = tmptex.height;
|
||||
tmptex.width = mipTile.lrs - mipTile.uls + 1;
|
||||
tmptex.height = mipTile.lrt - mipTile.ult + 1;
|
||||
_getTextureDestData(tmptex, m_tempTextureHolder.data(), glInternalFormat, GetTexel, &line);
|
||||
if (sizeShift == 2)
|
||||
doubleTexture<u32>(m_tempTextureHolder.data(), tmptex.width, tmptex.height);
|
||||
else
|
||||
doubleTexture<u16>((u16*)m_tempTextureHolder.data(), tmptex.width, tmptex.height);
|
||||
tmptex.width = texWidth;
|
||||
tmptex.height = texHeight;
|
||||
} else {
|
||||
_getTextureDestData(tmptex, m_tempTextureHolder.data(), glInternalFormat, GetTexel, &line);
|
||||
}
|
||||
}
|
||||
|
||||
if ((config.generalEmulation.hacks&hack_LoadDepthTextures) != 0 && gDP.colorImage.address == gDP.depthImageAddress) {
|
||||
_loadDepthTexture(_pTexture, (u16*)m_tempTextureHolder.data());
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_toggleDumpTex &&
|
||||
config.textureFilter.txHiresEnable != 0 &&
|
||||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||
txfilter_dmptx((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||
tmptex.width, (u16)u32(glInternalFormat),
|
||||
(unsigned short)(_pTexture->format << 8 | _pTexture->size),
|
||||
ricecrc);
|
||||
}
|
||||
|
||||
bool bLoaded = false;
|
||||
bool needEnhance = (config.textureFilter.txEnhancementMode | config.textureFilter.txFilterMode) != 0 &&
|
||||
_pTexture->max_level == 0 &&
|
||||
TFH.isInited();
|
||||
if (needEnhance) {
|
||||
if (config.textureFilter.txFilterIgnoreBG != 0) {
|
||||
switch (GBI.getMicrocodeType()) {
|
||||
case S2DEX_1_07:
|
||||
case S2DEX_1_03:
|
||||
case S2DEX_1_05:
|
||||
needEnhance = RSP.cmd != 0x01 && RSP.cmd != 0x02;
|
||||
break;
|
||||
case S2DEX2:
|
||||
needEnhance = RSP.cmd != 0x09 && RSP.cmd != 0x0A;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needEnhance) {
|
||||
GHQTexInfo ghqTexInfo;
|
||||
if (txfilter_filter((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||
(u16)u32(glInternalFormat), (uint64)_pTexture->crc,
|
||||
&ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) {
|
||||
if (ghqTexInfo.width % 2 != 0 &&
|
||||
ghqTexInfo.format != u32(internalcolorFormat::RGBA8) &&
|
||||
m_curUnpackAlignment > 1)
|
||||
gfxContext.setTextureUnpackAlignment(2);
|
||||
ghqTexInfo.format = gfxContext.convertInternalTextureFormat(ghqTexInfo.format);
|
||||
Context::InitTextureParams params;
|
||||
params.handle = _pTexture->name;
|
||||
params.textureUnitIndex = textureIndices::Tex[_tile];
|
||||
params.mipMapLevel = 0;
|
||||
params.msaaLevel = 0;
|
||||
params.width = ghqTexInfo.width;
|
||||
params.height = ghqTexInfo.height;
|
||||
params.internalFormat = InternalColorFormatParam(ghqTexInfo.format);
|
||||
params.format = ColorFormatParam(ghqTexInfo.texture_format);
|
||||
params.dataType = DatatypeParam(ghqTexInfo.pixel_type);
|
||||
params.data = ghqTexInfo.data;
|
||||
gfxContext.init2DTexture(params);
|
||||
_updateCachedTexture(ghqTexInfo, _pTexture, tmptex.width, tmptex.height);
|
||||
bLoaded = true;
|
||||
}
|
||||
}
|
||||
if (!bLoaded) {
|
||||
if (tmptex.width % 2 != 0 &&
|
||||
glInternalFormat != internalcolorFormat::RGBA8 &&
|
||||
m_curUnpackAlignment > 1)
|
||||
gfxContext.setTextureUnpackAlignment(2);
|
||||
Context::InitTextureParams params;
|
||||
params.handle = _pTexture->name;
|
||||
params.textureUnitIndex = textureIndices::Tex[_tile];
|
||||
params.mipMapLevel = mipLevel;
|
||||
params.mipMapLevels = _pTexture->max_level + 1;
|
||||
params.msaaLevel = 0;
|
||||
params.width = tmptex.width;
|
||||
params.height = tmptex.height;
|
||||
params.internalFormat = gfxContext.convertInternalTextureFormat(u32(glInternalFormat));
|
||||
params.format = colorFormat::RGBA;
|
||||
params.dataType = glType;
|
||||
params.data = m_tempTextureHolder.data();
|
||||
gfxContext.init2DTexture(params);
|
||||
}
|
||||
if (mipLevel == _pTexture->max_level)
|
||||
break;
|
||||
++mipLevel;
|
||||
const u32 tileMipLevel = gSP.texture.tile + mipLevel + 1;
|
||||
gDPTile & mipTile = gDP.tiles[tileMipLevel];
|
||||
line = mipTile.line;
|
||||
tmptex.tMem = mipTile.tmem;
|
||||
tmptex.palette = mipTile.palette;
|
||||
tmptex.maskS = mipTile.masks;
|
||||
tmptex.maskT = mipTile.maskt;
|
||||
tmptex.format = mipTile.format;
|
||||
tmptex.size = mipTile.size;
|
||||
TileSizes sizes;
|
||||
_calcTileSizes(tileMipLevel, sizes, nullptr);
|
||||
tmptex.clampWidth = sizes.clampWidth;
|
||||
tmptex.clampHeight = sizes.clampHeight;
|
||||
// Insure mip-map levels size consistency.
|
||||
if (tmptex.width > 1)
|
||||
tmptex.width >>= 1;
|
||||
if (tmptex.height > 1)
|
||||
tmptex.height >>= 1;
|
||||
_pTexture->textureBytes += (tmptex.width * tmptex.height) << sizeShift;
|
||||
}
|
||||
if (m_curUnpackAlignment > 1)
|
||||
gfxContext.setTextureUnpackAlignment(m_curUnpackAlignment);
|
||||
}
|
||||
|
||||
void TextureCache::_loadAccurate(u32 _tile, CachedTexture *_pTexture)
|
||||
{
|
||||
u64 ricecrc = 0;
|
||||
if (_loadHiresTexture(_tile, _pTexture, ricecrc))
|
||||
|
@ -1125,28 +1324,12 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
|||
}
|
||||
_pTexture->textureBytes = (_pTexture->width * _pTexture->height) << sizeShift;
|
||||
|
||||
// RAII holder for texture data
|
||||
class TexData
|
||||
{
|
||||
public:
|
||||
TexData(u32 bytes)
|
||||
{
|
||||
pData = (u32*)malloc(bytes);
|
||||
assert(pData != NULL);
|
||||
}
|
||||
~TexData()
|
||||
{
|
||||
free(pData);
|
||||
pData = NULL;
|
||||
}
|
||||
u32 * get() const
|
||||
{
|
||||
return pData;
|
||||
}
|
||||
private:
|
||||
u32 *pData = NULL;
|
||||
} texData(std::max((_pTexture->textureBytes + 8*sizeof(u32)), MIPMAP_TILE_WIDTH * sizeof(u32))
|
||||
* (_pTexture->max_level + 1));
|
||||
unsigned int totalTexSize = std::max(static_cast<u32>(_pTexture->textureBytes/sizeof(u32) + 8), MIPMAP_TILE_WIDTH)
|
||||
* (_pTexture->max_level + 1);
|
||||
|
||||
if (m_tempTextureHolder.size() < totalTexSize) {
|
||||
m_tempTextureHolder.resize(totalTexSize);
|
||||
}
|
||||
|
||||
GetTexelFunc GetTexel;
|
||||
InternalColorFormatParam glInternalFormat;
|
||||
|
@ -1180,15 +1363,15 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
|||
while (true)
|
||||
{
|
||||
const u32 tileSizePacked = texDataOffset | (tmptex.width << 16) | (tmptex.height << 24);
|
||||
texData.get()[mipLevel] = tileSizePacked;
|
||||
m_tempTextureHolder[mipLevel] = tileSizePacked;
|
||||
|
||||
getLoadParams(tmptex.format, tmptex.size);
|
||||
_getTextureDestData(tmptex, texData.get() + texDataOffset, glInternalFormat, GetTexel, &line);
|
||||
_getTextureDestData(tmptex, &m_tempTextureHolder[texDataOffset], glInternalFormat, GetTexel, &line);
|
||||
|
||||
if (m_toggleDumpTex &&
|
||||
config.textureFilter.txHiresEnable != 0 &&
|
||||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||
txfilter_dmptx((u8*)texData.get() + texDataOffset, tmptex.width, tmptex.height,
|
||||
txfilter_dmptx((u8*)(m_tempTextureHolder.data() + texDataOffset), tmptex.width, tmptex.height,
|
||||
tmptex.width, (u16)u32(glInternalFormat),
|
||||
(unsigned short)(_pTexture->format << 8 | _pTexture->size),
|
||||
ricecrc);
|
||||
|
@ -1228,7 +1411,7 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
|||
params.internalFormat = gfxContext.convertInternalTextureFormat(u32(glInternalFormat));
|
||||
params.format = colorFormat::RGBA;
|
||||
params.dataType = glType;
|
||||
params.data = texData.get();
|
||||
params.data = m_tempTextureHolder.data();
|
||||
gfxContext.init2DTexture(params);
|
||||
_pTexture->mipmapAtlasWidth = params.width;
|
||||
_pTexture->mipmapAtlasHeight = params.height;
|
||||
|
@ -1236,17 +1419,17 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
|||
else
|
||||
{
|
||||
getLoadParams(tmptex.format, tmptex.size);
|
||||
_getTextureDestData(tmptex, texData.get(), glInternalFormat, GetTexel, &line);
|
||||
_getTextureDestData(tmptex, m_tempTextureHolder.data(), glInternalFormat, GetTexel, &line);
|
||||
|
||||
if ((config.generalEmulation.hacks&hack_LoadDepthTextures) != 0 && gDP.colorImage.address == gDP.depthImageAddress) {
|
||||
_loadDepthTexture(_pTexture, (u16*)texData.get());
|
||||
_loadDepthTexture(_pTexture, (u16*)m_tempTextureHolder.data());
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_toggleDumpTex &&
|
||||
config.textureFilter.txHiresEnable != 0 &&
|
||||
config.hotkeys.enabledKeys[Config::HotKey::hkTexDump] != 0) {
|
||||
txfilter_dmptx((u8*)texData.get(), tmptex.width, tmptex.height,
|
||||
txfilter_dmptx((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||
tmptex.width, (u16)u32(glInternalFormat),
|
||||
(unsigned short)(_pTexture->format << 8 | _pTexture->size),
|
||||
ricecrc);
|
||||
|
@ -1273,7 +1456,7 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
|||
|
||||
if (needEnhance) {
|
||||
GHQTexInfo ghqTexInfo;
|
||||
if (txfilter_filter((u8*)texData.get(), tmptex.width, tmptex.height,
|
||||
if (txfilter_filter((u8*)m_tempTextureHolder.data(), tmptex.width, tmptex.height,
|
||||
(u16)u32(glInternalFormat), (uint64)_pTexture->crc,
|
||||
&ghqTexInfo) != 0 && ghqTexInfo.data != nullptr) {
|
||||
if (ghqTexInfo.width % 2 != 0 &&
|
||||
|
@ -1313,7 +1496,7 @@ void TextureCache::_load(u32 _tile, CachedTexture *_pTexture)
|
|||
params.internalFormat = gfxContext.convertInternalTextureFormat(u32(glInternalFormat));
|
||||
params.format = colorFormat::RGBA;
|
||||
params.dataType = glType;
|
||||
params.data = texData.get();
|
||||
params.data = m_tempTextureHolder.data();
|
||||
gfxContext.init2DTexture(params);
|
||||
}
|
||||
}
|
||||
|
@ -1565,6 +1748,14 @@ void TextureCache::update(u32 _t)
|
|||
return;
|
||||
}
|
||||
|
||||
if (_t == 1 && needReplaceTex1ByTex0()) {
|
||||
current[1] = current[0];
|
||||
if (current[1] != nullptr) {
|
||||
activateTexture(1, current[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (gSP.texture.tile == 7 &&
|
||||
_t == 0 &&
|
||||
gSP.textureTile[0] == gDP.loadTile &&
|
||||
|
@ -1660,7 +1851,11 @@ void TextureCache::update(u32 _t)
|
|||
pCurrent->offsetS = 0.0f;
|
||||
pCurrent->offsetT = 0.0f;
|
||||
|
||||
_load(_t, pCurrent);
|
||||
if (config.generalEmulation.enableInaccurateTextureCoordinates) {
|
||||
_loadFast(_t, pCurrent);
|
||||
} else {
|
||||
_loadAccurate(_t, pCurrent);
|
||||
}
|
||||
activateTexture( _t, pCurrent );
|
||||
|
||||
current[_t] = pCurrent;
|
||||
|
@ -1686,4 +1881,11 @@ void getTextureShiftScale(u32 t, const TextureCache & cache, f32 & shiftScaleS,
|
|||
shiftScaleT = (f32)(1 << (16 - gSP.textureTile[t]->shiftt));
|
||||
else if (gSP.textureTile[t]->shiftt > 0)
|
||||
shiftScaleT /= (f32)(1 << gSP.textureTile[t]->shiftt);
|
||||
}
|
||||
}
|
||||
|
||||
bool needReplaceTex1ByTex0()
|
||||
{
|
||||
return config.generalEmulation.enableInaccurateTextureCoordinates &&
|
||||
gSP.texture.level == 0 && gDP.otherMode.textureLOD == G_TL_LOD && gDP.otherMode.textureDetail == G_TD_CLAMP;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <list>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <stddef.h> // for size_t
|
||||
|
||||
#include "CRC.h"
|
||||
|
@ -84,7 +85,8 @@ private:
|
|||
|
||||
void _checkCacheSize();
|
||||
CachedTexture * _addTexture(u64 _crc64);
|
||||
void _load(u32 _tile, CachedTexture *_pTexture);
|
||||
void _loadFast(u32 _tile, CachedTexture *_pTexture);
|
||||
void _loadAccurate(u32 _tile, CachedTexture *_pTexture);
|
||||
bool _loadHiresTexture(u32 _tile, CachedTexture *_pTexture, u64 & _ricecrc);
|
||||
void _loadBackground(CachedTexture *pTexture);
|
||||
bool _loadHiresBackground(CachedTexture *_pTexture, u64 & _ricecrc);
|
||||
|
@ -104,6 +106,7 @@ private:
|
|||
u32 m_hits, m_misses;
|
||||
s32 m_curUnpackAlignment;
|
||||
bool m_toggleDumpTex;
|
||||
std::vector<u32> m_tempTextureHolder;
|
||||
#ifdef VC
|
||||
const size_t m_maxCacheSize = 1500;
|
||||
#else
|
||||
|
@ -113,6 +116,9 @@ private:
|
|||
|
||||
void getTextureShiftScale(u32 tile, const TextureCache & cache, f32 & shiftScaleS, f32 & shiftScaleT);
|
||||
|
||||
// Check for situation when Tex0 is used instead of Tex1
|
||||
bool needReplaceTex1ByTex0();
|
||||
|
||||
inline TextureCache & textureCache()
|
||||
{
|
||||
return TextureCache::get();
|
||||
|
|
|
@ -858,7 +858,7 @@ void gDPTextureRectangle(f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, s16 s, s1
|
|||
textureTileOrg[0] = gSP.textureTile[0];
|
||||
textureTileOrg[1] = gSP.textureTile[1];
|
||||
gSP.textureTile[0] = &gDP.tiles[tile];
|
||||
gSP.textureTile[1] = &gDP.tiles[(tile + 1) & 7];
|
||||
gSP.textureTile[1] = needReplaceTex1ByTex0() ? &gDP.tiles[tile] : &gDP.tiles[(tile + 1) & 7];
|
||||
|
||||
// HACK ALERT!
|
||||
if (s == 0x4000 && (gDP.colorImage.width + gSP.textureTile[0]->uls < 512))
|
||||
|
@ -973,7 +973,7 @@ void LLETriangle::start(u32 _tile)
|
|||
m_textureScaleOrg[1] = gSP.texture.scalet;
|
||||
gSP.texture.tile = _tile;
|
||||
gSP.textureTile[0] = &gDP.tiles[_tile];
|
||||
gSP.textureTile[1] = &gDP.tiles[(_tile + 1) & 7];
|
||||
gSP.textureTile[1] = needReplaceTex1ByTex0() ? &gDP.tiles[_tile] : &gDP.tiles[(_tile + 1) & 7];
|
||||
gSP.texture.scales = 1.0f;
|
||||
gSP.texture.scalet = 1.0f;
|
||||
m_flushed = false;
|
||||
|
|
|
@ -163,6 +163,8 @@ bool Config_SetDefault()
|
|||
assert(res == M64ERR_SUCCESS);
|
||||
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableHybridFilter", config.generalEmulation.enableHybridFilter, "Enable hybrid integer scaling filter. Can be slow with low-end GPUs.");
|
||||
assert(res == M64ERR_SUCCESS);
|
||||
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableInaccurateTextureCoordinates", config.generalEmulation.enableInaccurateTextureCoordinates, "Use fast but less accurate shaders. Can help with low-end GPUs.");
|
||||
assert(res == M64ERR_SUCCESS);
|
||||
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableFragmentDepthWrite", config.generalEmulation.enableFragmentDepthWrite, "Enable writing of fragment depth. Some mobile GPUs do not support it, thus made optional. Leave enabled.");
|
||||
assert(res == M64ERR_SUCCESS);
|
||||
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCustomSettings", config.generalEmulation.enableCustomSettings, "Use GLideN64 per-game settings.");
|
||||
|
@ -508,6 +510,7 @@ void Config_LoadConfig()
|
|||
config.generalEmulation.enableShadersStorage = ConfigGetParamBool(g_configVideoGliden64, "EnableShadersStorage");
|
||||
config.generalEmulation.enableLegacyBlending = ConfigGetParamBool(g_configVideoGliden64, "EnableLegacyBlending");
|
||||
config.generalEmulation.enableHybridFilter = ConfigGetParamBool(g_configVideoGliden64, "EnableHybridFilter");
|
||||
config.generalEmulation.enableInaccurateTextureCoordinates = ConfigGetParamBool(g_configVideoGliden64, "EnableInaccurateTextureCoordinates");
|
||||
config.generalEmulation.enableFragmentDepthWrite = ConfigGetParamBool(g_configVideoGliden64, "EnableFragmentDepthWrite");
|
||||
config.generalEmulation.enableCustomSettings = ConfigGetParamBool(g_configVideoGliden64, "EnableCustomSettings");
|
||||
#if defined(OS_ANDROID) || defined(OS_IOS)
|
||||
|
|
Loading…
Reference in New Issue
Block a user