Add an experiment with using a texture for tests.

Using an option for now so it's easy to test, if it works well we can
maybe remove the option.
This commit is contained in:
Unknown W. Brackets 2014-08-24 15:26:38 -07:00
parent 780ed765c7
commit 94c1271761
17 changed files with 362 additions and 55 deletions

View file

@ -1327,6 +1327,8 @@ add_library(GPU OBJECT
GPU/GLES/GLES_GPU.h
GPU/GLES/FragmentShaderGenerator.cpp
GPU/GLES/FragmentShaderGenerator.h
GPU/GLES/FragmentTestCache.cpp
GPU/GLES/FragmentTestCache.h
GPU/GLES/Framebuffer.cpp
GPU/GLES/Framebuffer.h
GPU/GLES/ShaderManager.cpp

View file

@ -441,6 +441,7 @@ static ConfigSetting graphicsSettings[] = {
ReportedConfigSetting("MemBlockTransferGPU", &g_Config.bBlockTransferGPU, true),
ReportedConfigSetting("DisableSlowFramebufEffects", &g_Config.bDisableSlowFramebufEffects, false),
ReportedConfigSetting("FragmentTestCache", &g_Config.bFragmentTestCache, true),
ConfigSetting(false),
};

View file

@ -161,6 +161,7 @@ public:
bool bAlphaMaskHack;
bool bBlockTransferGPU;
bool bDisableSlowFramebufEffects;
bool bFragmentTestCache;
int iSplineBezierQuality; // 0 = low , 1 = Intermediate , 2 = High
std::string sPostShaderName; // Off for off.

View file

@ -567,9 +567,13 @@ void GenerateFragmentShader(char *buffer) {
}
if (enableAlphaTest || enableColorTest) {
WRITE(p, "uniform vec4 u_alphacolorref;\n");
if (bitwiseOps && (enableColorTest || !alphaTestAgainstZero)) {
WRITE(p, "uniform ivec4 u_alphacolormask;\n");
if (g_Config.bFragmentTestCache) {
WRITE(p, "uniform sampler2D testtex;\n");
} else {
WRITE(p, "uniform vec4 u_alphacolorref;\n");
if (bitwiseOps && (enableColorTest || !alphaTestAgainstZero)) {
WRITE(p, "uniform ivec4 u_alphacolormask;\n");
}
}
}
if (stencilToAlpha && ReplaceAlphaWithStencilType() == STENCIL_VALUE_UNIFORM) {
@ -592,22 +596,24 @@ void GenerateFragmentShader(char *buffer) {
WRITE(p, "%s mediump vec2 v_texcoord;\n", varying);
}
if (enableAlphaTest && !alphaTestAgainstZero) {
if (bitwiseOps) {
WRITE(p, "int roundAndScaleTo255i(in float x) { return int(floor(x * 255.0 + 0.5)); }\n");
} else if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR) {
WRITE(p, "float roundTo255thf(in mediump float x) { mediump float y = x + (0.5/255.0); return y - fract(y * 255.0) * (1.0 / 255.0); }\n");
} else {
WRITE(p, "float roundAndScaleTo255f(in float x) { return floor(x * 255.0 + 0.5); }\n");
if (!g_Config.bFragmentTestCache) {
if (enableAlphaTest && !alphaTestAgainstZero) {
if (bitwiseOps) {
WRITE(p, "int roundAndScaleTo255i(in float x) { return int(floor(x * 255.0 + 0.5)); }\n");
} else if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR) {
WRITE(p, "float roundTo255thf(in mediump float x) { mediump float y = x + (0.5/255.0); return y - fract(y * 255.0) * (1.0 / 255.0); }\n");
} else {
WRITE(p, "float roundAndScaleTo255f(in float x) { return floor(x * 255.0 + 0.5); }\n");
}
}
}
if (enableColorTest) {
if (bitwiseOps) {
WRITE(p, "ivec3 roundAndScaleTo255iv(in vec3 x) { return ivec3(floor(x * 255.0 + 0.5)); }\n");
} else if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR) {
WRITE(p, "vec3 roundTo255thv(in vec3 x) { vec3 y = x + (0.5/255.0); return y - fract(y * 255.0) * (1.0 / 255.0); }\n");
} else {
WRITE(p, "vec3 roundAndScaleTo255v(in vec3 x) { return floor(x * 255.0 + 0.5); }\n");
if (enableColorTest) {
if (bitwiseOps) {
WRITE(p, "ivec3 roundAndScaleTo255iv(in vec3 x) { return ivec3(floor(x * 255.0 + 0.5)); }\n");
} else if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR) {
WRITE(p, "vec3 roundTo255thv(in vec3 x) { vec3 y = x + (0.5/255.0); return y - fract(y * 255.0) * (1.0 / 255.0); }\n");
} else {
WRITE(p, "vec3 roundAndScaleTo255v(in vec3 x) { return floor(x * 255.0 + 0.5); }\n");
}
}
}
@ -748,51 +754,68 @@ void GenerateFragmentShader(char *buffer) {
}
if (enableAlphaTest) {
GEComparison alphaTestFunc = gstate.getAlphaTestFunction();
const char *alphaTestFuncs[] = { "#", "#", " != ", " == ", " >= ", " > ", " <= ", " < " };
if (alphaTestFuncs[alphaTestFunc][0] != '#') {
if (alphaTestAgainstZero) {
// When testing against 0 (extremely common), we can avoid some math.
// 0.002 is approximately half of 1.0 / 255.0.
if (alphaTestFunc == GE_COMP_NOTEQUAL || alphaTestFunc == GE_COMP_GREATER) {
WRITE(p, " if (v.a < 0.002) discard;\n");
} else {
// Anything else is a test for == 0. Happens sometimes, actually...
WRITE(p, " if (v.a > 0.002) discard;\n");
}
} else if (bitwiseOps) {
WRITE(p, " if ((roundAndScaleTo255i(v.a) & u_alphacolormask.a) %s int(u_alphacolorref.a)) discard;\n", alphaTestFuncs[alphaTestFunc]);
} else if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR) {
// Work around bad PVR driver problem where equality check + discard just doesn't work.
if (alphaTestFunc != GE_COMP_NOTEQUAL)
WRITE(p, " if (roundTo255thf(v.a) %s u_alphacolorref.a) discard;\n", alphaTestFuncs[alphaTestFunc]);
if (alphaTestAgainstZero) {
GEComparison alphaTestFunc = gstate.getAlphaTestFunction();
// When testing against 0 (extremely common), we can avoid some math.
// 0.002 is approximately half of 1.0 / 255.0.
if (alphaTestFunc == GE_COMP_NOTEQUAL || alphaTestFunc == GE_COMP_GREATER) {
WRITE(p, " if (v.a < 0.002) discard;\n");
} else if (alphaTestFunc != GE_COMP_NEVER) {
// Anything else is a test for == 0. Happens sometimes, actually...
WRITE(p, " if (v.a > 0.002) discard;\n");
} else {
WRITE(p, " if (roundAndScaleTo255f(v.a) %s u_alphacolorref.a) discard;\n", alphaTestFuncs[alphaTestFunc]);
// NEVER has been logged as used by games, although it makes little sense - statically failing.
// Maybe we could discard the drawcall, but it's pretty rare. Let's just statically discard here.
WRITE(p, " discard;\n");
}
} else if (g_Config.bFragmentTestCache) {
WRITE(p, " float aResult = %s(testtex, vec2(v.a, 0)).a;\n", texture);
WRITE(p, " if (aResult < 0.5) discard;\n", texture);
} else {
// NEVER has been logged as used by games, although it makes little sense - statically failing.
// Maybe we could discard the drawcall, but it's pretty rare. Let's just statically discard here.
WRITE(p, " discard;\n");
GEComparison alphaTestFunc = gstate.getAlphaTestFunction();
const char *alphaTestFuncs[] = { "#", "#", " != ", " == ", " >= ", " > ", " <= ", " < " };
if (alphaTestFuncs[alphaTestFunc][0] != '#') {
if (bitwiseOps) {
WRITE(p, " if ((roundAndScaleTo255i(v.a) & u_alphacolormask.a) %s int(u_alphacolorref.a)) discard;\n", alphaTestFuncs[alphaTestFunc]);
} else if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR) {
// Work around bad PVR driver problem where equality check + discard just doesn't work.
if (alphaTestFunc != GE_COMP_NOTEQUAL) {
WRITE(p, " if (roundTo255thf(v.a) %s u_alphacolorref.a) discard;\n", alphaTestFuncs[alphaTestFunc]);
}
} else {
WRITE(p, " if (roundAndScaleTo255f(v.a) %s u_alphacolorref.a) discard;\n", alphaTestFuncs[alphaTestFunc]);
}
} else {
// This means NEVER. See above.
WRITE(p, " discard;\n");
}
}
}
if (enableColorTest) {
GEComparison colorTestFunc = gstate.getColorTestFunction();
const char *colorTestFuncs[] = { "#", "#", " != ", " == " };
if (colorTestFuncs[colorTestFunc][0] != '#') {
if (bitwiseOps) {
// Apparently GLES3 does not support vector bitwise ops.
WRITE(p, " ivec3 v_scaled = roundAndScaleTo255iv(v.rgb);\n");
const char *maskedFragColor = "ivec3(v_scaled.r & u_alphacolormask.r, v_scaled.g & u_alphacolormask.g, v_scaled.b & u_alphacolormask.b)";
const char *maskedColorRef = "ivec3(int(u_alphacolorref.r) & u_alphacolormask.r, int(u_alphacolorref.g) & u_alphacolormask.g, int(u_alphacolorref.b) & u_alphacolormask.b)";
WRITE(p, " if (%s %s %s) discard;\n", maskedFragColor, colorTestFuncs[colorTestFunc], maskedColorRef);
} else if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR) {
WRITE(p, " if (roundTo255thv(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]);
} else {
WRITE(p, " if (roundAndScaleTo255v(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]);
}
if (g_Config.bFragmentTestCache) {
WRITE(p, " float rResult = %s(testtex, vec2(v.r, 0)).r;\n", texture);
WRITE(p, " float gResult = %s(testtex, vec2(v.g, 0)).g;\n", texture);
WRITE(p, " float bResult = %s(testtex, vec2(v.b, 0)).b;\n", texture);
WRITE(p, " if (rResult < 0.5 || gResult < 0.5 || bResult < 0.5) discard;\n", texture);
} else {
WRITE(p, " discard;\n");
GEComparison colorTestFunc = gstate.getColorTestFunction();
const char *colorTestFuncs[] = { "#", "#", " != ", " == " };
if (colorTestFuncs[colorTestFunc][0] != '#') {
if (bitwiseOps) {
// Apparently GLES3 does not support vector bitwise ops.
WRITE(p, " ivec3 v_scaled = roundAndScaleTo255iv(v.rgb);\n");
const char *maskedFragColor = "ivec3(v_scaled.r & u_alphacolormask.r, v_scaled.g & u_alphacolormask.g, v_scaled.b & u_alphacolormask.b)";
const char *maskedColorRef = "ivec3(int(u_alphacolorref.r) & u_alphacolormask.r, int(u_alphacolorref.g) & u_alphacolormask.g, int(u_alphacolorref.b) & u_alphacolormask.b)";
WRITE(p, " if (%s %s %s) discard;\n", maskedFragColor, colorTestFuncs[colorTestFunc], maskedColorRef);
} else if (gl_extensions.gpuVendor == GPU_VENDOR_POWERVR) {
WRITE(p, " if (roundTo255thv(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]);
} else {
WRITE(p, " if (roundAndScaleTo255v(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]);
}
} else {
WRITE(p, " discard;\n");
}
}
}

View file

@ -0,0 +1,167 @@
// Copyright (c) 2014- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Core/Config.h"
#include "GPU/GLES/FragmentTestCache.h"
#include "GPU/GPUState.h"
static const int FRAGTEST_TEXTURE_OLD_AGE = 123;
FragmentTestCache::FragmentTestCache() : textureCache_(NULL), lastTexture_(0) {
scratchpad_ = new u8[256 * 4];
}
FragmentTestCache::~FragmentTestCache() {
Clear();
delete [] scratchpad_;
}
void FragmentTestCache::BindTestTexture(GLenum unit) {
if (!g_Config.bFragmentTestCache) {
return;
}
const FragmentTestID id = GenerateTestID();
const auto cached = cache_.find(id);
if (cached != cache_.end()) {
GLuint tex = cached->second.texture;
if (tex == lastTexture_) {
// Already bound, hurray.
return;
}
glActiveTexture(unit);
glBindTexture(GL_TEXTURE_2D, tex);
// Always return to the default.
glActiveTexture(GL_TEXTURE0);
return;
}
const u8 rRef = (gstate.getColorTestRef() >> 0) & 0xFF;
const u8 rMask = (gstate.getColorTestMask() >> 0) & 0xFF;
const u8 gRef = (gstate.getColorTestRef() >> 8) & 0xFF;
const u8 gMask = (gstate.getColorTestMask() >> 8) & 0xFF;
const u8 bRef = (gstate.getColorTestRef() >> 16) & 0xFF;
const u8 bMask = (gstate.getColorTestMask() >> 16) & 0xFF;
const u8 aRef = gstate.getAlphaTestRef();
const u8 aMask = gstate.getAlphaTestMask();
const u8 refs[4] = {rRef, gRef, bRef, aRef};
const u8 masks[4] = {rMask, gMask, bMask, aMask};
const GEComparison funcs[4] = {gstate.getColorTestFunction(), gstate.getColorTestFunction(), gstate.getColorTestFunction(), gstate.getAlphaTestFunction()};
const bool valid[4] = {gstate.isColorTestEnabled(), gstate.isColorTestEnabled(), gstate.isColorTestEnabled(), gstate.isAlphaTestEnabled()};
glActiveTexture(unit);
// This will necessarily bind the texture.
const GLuint tex = CreateCache(funcs, refs, masks, valid);
// Always return to the default.
glActiveTexture(GL_TEXTURE0);
FragmentTestTexture item;
item.lastFrame = gpuStats.numFlips;
item.texture = tex;
cache_[id] = item;
}
FragmentTestID FragmentTestCache::GenerateTestID() const {
FragmentTestID id;
// Let's just keep it simple, it's all in here.
id.alpha = gstate.isAlphaTestEnabled() ? gstate.alphatest : 0;
if (gstate.isColorTestEnabled()) {
id.colorRefFunc = gstate.getColorTestFunction() | (gstate.getColorTestRef() << 8);
id.colorMask = gstate.getColorTestMask();
} else {
id.colorRefFunc = 0;
id.colorMask = 0;
}
return id;
}
GLuint FragmentTestCache::CreateCache(const GEComparison funcs[4], const u8 refs[4], const u8 masks[4], const bool valid[4]) {
// TODO: Might it be better to use GL_ALPHA for simple textures?
// TODO: Experiment with 4-bit/etc. textures.
GLuint tex = textureCache_->AllocTextureName();
glBindTexture(GL_TEXTURE_2D, tex);
// Build the logic map.
for (int color = 0; color < 256; ++color) {
for (int i = 0; i < 4; ++i) {
bool res;
if (valid[i]) {
switch (funcs[i]) {
case GE_COMP_NEVER:
res = false;
break;
case GE_COMP_ALWAYS:
res = true;
break;
case GE_COMP_EQUAL:
res = (color & masks[i]) == (refs[i] & masks[i]);
break;
case GE_COMP_NOTEQUAL:
res = (color & masks[i]) != (refs[i] & masks[i]);
break;
case GE_COMP_LESS:
res = (color & masks[i]) < (refs[i] & masks[i]);
break;
case GE_COMP_LEQUAL:
res = (color & masks[i]) <= (refs[i] & masks[i]);
break;
case GE_COMP_GREATER:
res = (color & masks[i]) > (refs[i] & masks[i]);
break;
case GE_COMP_GEQUAL:
res = (color & masks[i]) >= (refs[i] & masks[i]);
break;
}
} else {
res = true;
}
scratchpad_[color * 4 + i] = res ? 0xFF : 0;
}
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, scratchpad_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
return tex;
}
void FragmentTestCache::Clear(bool deleteThem) {
if (deleteThem) {
for (auto tex = cache_.begin(); tex != cache_.end(); ++tex) {
glDeleteTextures(1, &tex->second.texture);
}
}
cache_.clear();
lastTexture_ = 0;
}
void FragmentTestCache::Decimate() {
for (auto tex = cache_.begin(); tex != cache_.end(); ) {
if (tex->second.lastFrame + FRAGTEST_TEXTURE_OLD_AGE < gpuStats.numFlips) {
glDeleteTextures(1, &tex->second.texture);
cache_.erase(tex++);
} else {
++tex;
}
}
lastTexture_ = 0;
}

View file

@ -0,0 +1,83 @@
// Copyright (c) 2014- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#pragma once
#include <map>
#include "Common/CommonTypes.h"
#include "gfx_es2/gl_state.h"
#include "GPU/ge_constants.h"
#include "GPU/GLES/TextureCache.h"
struct FragmentTestID {
union {
struct {
u32 alpha;
u32 colorRefFunc;
u32 colorMask;
};
u32 d[3];
};
bool operator < (const FragmentTestID &other) const {
for (size_t i = 0; i < sizeof(d) / sizeof(u32); i++) {
if (d[i] < other.d[i])
return true;
if (d[i] > other.d[i])
return false;
}
return false;
}
bool operator == (const FragmentTestID &other) const {
for (size_t i = 0; i < sizeof(d) / sizeof(u32); i++) {
if (d[i] != other.d[i])
return false;
}
return true;
}
};
struct FragmentTestTexture {
GLuint texture;
int lastFrame;
};
class FragmentTestCache {
public:
FragmentTestCache();
~FragmentTestCache();
void SetTextureCache(TextureCache *tc) {
textureCache_ = tc;
}
void BindTestTexture(GLenum unit);
void Clear(bool deleteThem = true);
void Decimate();
private:
GLuint CreateCache(const GEComparison funcs[4], const u8 refs[4], const u8 masks[4], const bool valid[4]);
FragmentTestID GenerateTestID() const;
TextureCache *textureCache_;
std::map<FragmentTestID, FragmentTestTexture> cache_;
u8 *scratchpad_;
GLuint lastTexture_;
};

View file

@ -397,6 +397,7 @@ GLES_GPU::GLES_GPU()
transformDraw_.SetShaderManager(shaderManager_);
transformDraw_.SetTextureCache(&textureCache_);
transformDraw_.SetFramebufferManager(&framebufferManager_);
transformDraw_.SetFragmentTestCache(&fragmentTestCache_);
framebufferManager_.Init();
framebufferManager_.SetTextureCache(&textureCache_);
framebufferManager_.SetShaderManager(shaderManager_);
@ -404,6 +405,7 @@ GLES_GPU::GLES_GPU()
textureCache_.SetFramebufferManager(&framebufferManager_);
textureCache_.SetDepalShaderCache(&depalShaderCache_);
textureCache_.SetShaderManager(shaderManager_);
fragmentTestCache_.SetTextureCache(&textureCache_);
// Sanity check gstate
if ((int *)&gstate.transferstart - (int *)&gstate != 0xEA) {
@ -447,6 +449,7 @@ GLES_GPU::~GLES_GPU() {
framebufferManager_.DestroyAllFBOs();
shaderManager_->ClearCache(true);
depalShaderCache_.Clear();
fragmentTestCache_.Clear();
delete shaderManager_;
glstate.SetVSyncInterval(0);
}
@ -484,6 +487,7 @@ void GLES_GPU::DeviceLost() {
// TransformDraw has registered as a GfxResourceHolder.
shaderManager_->ClearCache(false);
textureCache_.Clear(false);
fragmentTestCache_.Clear(false);
depalShaderCache_.Clear();
framebufferManager_.DeviceLost();
@ -585,6 +589,7 @@ void GLES_GPU::BeginFrameInternal() {
textureCache_.StartFrame();
transformDraw_.DecimateTrackedVertexArrays();
depalShaderCache_.Decimate();
fragmentTestCache_.Decimate();
if (dumpNextFrame_) {
NOTICE_LOG(G3D, "DUMPING THIS FRAME");

View file

@ -27,6 +27,7 @@
#include "GPU/GLES/TransformPipeline.h"
#include "GPU/GLES/TextureCache.h"
#include "GPU/GLES/DepalettizeShader.h"
#include "GPU/GLES/FragmentTestCache.h"
class ShaderManager;
class LinkedShader;
@ -173,6 +174,7 @@ private:
TextureCache textureCache_;
DepalShaderCache depalShaderCache_;
TransformDrawEngine transformDraw_;
FragmentTestCache fragmentTestCache_;
ShaderManager *shaderManager_;
bool resized_;

View file

@ -147,6 +147,7 @@ LinkedShader::LinkedShader(Shader *vs, Shader *fs, u32 vertType, bool useHWTrans
u_alphacolorref = glGetUniformLocation(program, "u_alphacolorref");
u_alphacolormask = glGetUniformLocation(program, "u_alphacolormask");
u_stencilReplaceValue = glGetUniformLocation(program, "u_stencilReplaceValue");
u_testtex = glGetUniformLocation(program, "testtex");
u_fbotex = glGetUniformLocation(program, "fbotex");
u_blendFixA = glGetUniformLocation(program, "u_blendFixA");
@ -258,6 +259,7 @@ LinkedShader::LinkedShader(Shader *vs, Shader *fs, u32 vertType, bool useHWTrans
// Default uniform values
glUniform1i(u_tex, 0);
glUniform1i(u_fbotex, 1);
glUniform1i(u_testtex, 2);
// The rest, use the "dirty" mechanism.
dirtyUniforms = DIRTY_ALL;
use(vertType, previous);

View file

@ -82,6 +82,7 @@ public:
// Fragment processing inputs
int u_alphacolorref;
int u_alphacolormask;
int u_testtex;
int u_fogcolor;
int u_fogcoef;

View file

@ -639,6 +639,10 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
} else {
glstate.stencilTest.disable();
}
if (gstate.isAlphaTestEnabled() || gstate.isColorTestEnabled()) {
fragmentTestCache_->BindTestTexture(GL_TEXTURE2);
}
}
bool throughmode = gstate.isModeThrough();

View file

@ -80,6 +80,7 @@
#include "GPU/Common/TextureDecoder.h"
#include "GPU/Common/SplineCommon.h"
#include "GPU/GLES/FragmentTestCache.h"
#include "GPU/GLES/StateMapping.h"
#include "GPU/GLES/TextureCache.h"
#include "GPU/GLES/TransformPipeline.h"

View file

@ -29,6 +29,7 @@ class LinkedShader;
class ShaderManager;
class TextureCache;
class FramebufferManager;
class FragmentTestCache;
struct TransformedVertex;
struct DecVtxFormat;
@ -116,6 +117,9 @@ public:
void SetFramebufferManager(FramebufferManager *fbManager) {
framebufferManager_ = fbManager;
}
void SetFragmentTestCache(FragmentTestCache *testCache) {
fragmentTestCache_ = testCache;
}
void InitDeviceObjects();
void DestroyDeviceObjects();
void GLLost();
@ -236,6 +240,7 @@ private:
ShaderManager *shaderManager_;
TextureCache *textureCache_;
FramebufferManager *framebufferManager_;
FragmentTestCache *fragmentTestCache_;
enum { MAX_DEFERRED_DRAW_CALLS = 128 };
DeferredDrawCall drawCalls[MAX_DEFERRED_DRAW_CALLS];

View file

@ -192,6 +192,7 @@
<ClInclude Include="GeDisasm.h" />
<ClInclude Include="GLES\DepalettizeShader.h" />
<ClInclude Include="GLES\FragmentShaderGenerator.h" />
<ClInclude Include="GLES\FragmentTestCache.h" />
<ClInclude Include="GLES\Framebuffer.h" />
<ClInclude Include="GLES\GLES_GPU.h" />
<ClInclude Include="GLES\ShaderManager.h" />
@ -245,6 +246,7 @@
<ClCompile Include="GeDisasm.cpp" />
<ClCompile Include="GLES\DepalettizeShader.cpp" />
<ClCompile Include="GLES\FragmentShaderGenerator.cpp" />
<ClCompile Include="GLES\FragmentTestCache.cpp" />
<ClCompile Include="GLES\Framebuffer.cpp" />
<ClCompile Include="GLES\GLES_GPU.cpp" />
<ClCompile Include="GLES\ShaderManager.cpp" />

View file

@ -168,6 +168,9 @@
<ClInclude Include="GLES\DepalettizeShader.h">
<Filter>GLES</Filter>
</ClInclude>
<ClInclude Include="GLES\FragmentTestCache.h">
<Filter>GLES</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Math3D.cpp">
@ -317,6 +320,9 @@
<ClCompile Include="GLES\StencilBuffer.cpp">
<Filter>GLES</Filter>
</ClCompile>
<ClCompile Include="GLES\FragmentTestCache.cpp">
<Filter>GLES</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />

View file

@ -28,6 +28,7 @@ SOURCES += $$P/GPU/GeDisasm.cpp \ # GPU
$$P/GPU/Null/NullGpu.cpp \
$$P/GPU/GLES/DepalettizeShader.cpp \
$$P/GPU/GLES/FragmentShaderGenerator.cpp \
$$P/GPU/GLES/FragmentTestCache.cpp \
$$P/GPU/GLES/Framebuffer.cpp \
$$P/GPU/GLES/GLES_GPU.cpp \
$$P/GPU/GLES/ShaderManager.cpp \

View file

@ -155,6 +155,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/GPU/GLES/ShaderManager.cpp.arm \
$(SRC)/GPU/GLES/VertexShaderGenerator.cpp.arm \
$(SRC)/GPU/GLES/FragmentShaderGenerator.cpp.arm \
$(SRC)/GPU/GLES/FragmentTestCache.cpp.arm \
$(SRC)/GPU/GLES/TextureScaler.cpp \
$(SRC)/GPU/GLES/Spline.cpp \
$(SRC)/GPU/Null/NullGpu.cpp \