Skip to content

Commit

Permalink
More GLRenderManager
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Jan 27, 2018
1 parent 376d92f commit bd68181
Show file tree
Hide file tree
Showing 18 changed files with 206 additions and 231 deletions.
2 changes: 1 addition & 1 deletion GPU/Common/TextureCacheCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ void TextureCacheCommon::SetTexture(bool force) {
// Exponential backoff up to 512 frames. Textures are often reused.
if (entry->numFrames > 32) {
// Also, try to add some "randomness" to avoid rehashing several textures the same frame.
entry->framesUntilNextFullHash = std::min(512, entry->numFrames) + (entry->textureName & 15);
entry->framesUntilNextFullHash = std::min(512, entry->numFrames) + (((intptr_t)entry->textureName >> 8) & 15);
} else {
entry->framesUntilNextFullHash = entry->numFrames;
}
Expand Down
4 changes: 3 additions & 1 deletion GPU/Common/TextureCacheCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ struct SamplerCacheKey {
}
};

class GLRTexture;

// TODO: Shrink this struct. There is some fluff.
struct TexCacheEntry {
~TexCacheEntry() {
Expand Down Expand Up @@ -132,7 +134,7 @@ struct TexCacheEntry {
u16 dim;
u16 bufw;
union {
u32 textureName;
GLRTexture *textureName;
void *texturePtr;
CachedTextureVulkan *vkTex;
};
Expand Down
108 changes: 30 additions & 78 deletions GPU/GLES/DepalettizeShaderGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ static bool CheckShaderCompileSuccess(GLuint shader, const char *code) {
}
}

DepalShaderCacheGLES::DepalShaderCacheGLES() {
DepalShaderCacheGLES::DepalShaderCacheGLES(Draw::DrawContext *draw) {
render_ = (GLRenderManager *)draw->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
// Pre-build the vertex program
useGL3_ = gl_extensions.GLES3 || gl_extensions.VersionGEThan(3, 3);

Expand All @@ -102,25 +103,12 @@ DepalShaderCacheGLES::~DepalShaderCacheGLES() {
}

bool DepalShaderCacheGLES::CreateVertexShader() {
if (vertexShaderFailed_) {
return false;
}

vertexShader_ = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader_, 1, useGL3_ ? &depalVShader300 : &depalVShader100, 0);
glCompileShader(vertexShader_);

if (!CheckShaderCompileSuccess(vertexShader_, useGL3_ ? depalVShader300 : depalVShader100)) {
glDeleteShader(vertexShader_);
vertexShader_ = 0;
// Don't try to recompile.
vertexShaderFailed_ = true;
}

return !vertexShaderFailed_;
std::string src(useGL3_ ? depalVShader300 : depalVShader100);
vertexShader_ = render_->CreateShader(GL_VERTEX_SHADER, src);
return true;
}

GLuint DepalShaderCacheGLES::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut) {
GLRTexture *DepalShaderCacheGLES::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut) {
u32 clutId = GetClutID(clutFormat, clutHash);

auto oldtex = texCache_.find(clutId);
Expand All @@ -133,18 +121,11 @@ GLuint DepalShaderCacheGLES::GetClutTexture(GEPaletteFormat clutFormat, const u3
int texturePixels = clutFormat == GE_CMODE_32BIT_ABGR8888 ? 256 : 512;

DepalTexture *tex = new DepalTexture();
glGenTextures(1, &tex->texture);
glBindTexture(GL_TEXTURE_2D, tex->texture);
tex->texture = render_->CreateTexture(GL_TEXTURE_2D);
GLuint components = dstFmt == GL_UNSIGNED_SHORT_5_6_5 ? GL_RGB : GL_RGBA;

GLuint components2 = components;

glTexImage2D(GL_TEXTURE_2D, 0, components, texturePixels, 1, 0, components2, dstFmt, (void *)rawClut);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
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);
render_->TextureImage(tex->texture, 0, texturePixels, 1, components, components2, dstFmt, (uint8_t *)rawClut, false);

tex->lastFrame = gpuStats.numFlips;
texCache_[clutId] = tex;
Expand All @@ -153,28 +134,28 @@ GLuint DepalShaderCacheGLES::GetClutTexture(GEPaletteFormat clutFormat, const u3

void DepalShaderCacheGLES::Clear() {
for (auto shader = cache_.begin(); shader != cache_.end(); ++shader) {
glDeleteShader(shader->second->fragShader);
render_->DeleteShader(shader->second->fragShader);
if (shader->second->program) {
glDeleteProgram(shader->second->program);
render_->DeleteProgram(shader->second->program);
}
delete shader->second;
}
cache_.clear();
for (auto tex = texCache_.begin(); tex != texCache_.end(); ++tex) {
glDeleteTextures(1, &tex->second->texture);
render_->DeleteTexture(tex->second->texture);
delete tex->second;
}
texCache_.clear();
if (vertexShader_) {
glDeleteShader(vertexShader_);
render_->DeleteShader(vertexShader_);
vertexShader_ = 0;
}
}

void DepalShaderCacheGLES::Decimate() {
for (auto tex = texCache_.begin(); tex != texCache_.end(); ) {
if (tex->second->lastFrame + DEPAL_TEXTURE_OLD_AGE < gpuStats.numFlips) {
glDeleteTextures(1, &tex->second->texture);
render_->DeleteTexture(tex->second->texture);
delete tex->second;
texCache_.erase(tex++);
} else {
Expand All @@ -201,64 +182,35 @@ DepalShader *DepalShaderCacheGLES::GetDepalettizeShader(uint32_t clutMode, GEBuf
char *buffer = new char[2048];

GenerateDepalShader(buffer, pixelFormat, useGL3_ ? GLSL_300 : GLSL_140);

std::string src(buffer);
GLRShader *fragShader = render_->CreateShader(GL_FRAGMENT_SHADER, src);

GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);

const char *buf = buffer;
glShaderSource(fragShader, 1, &buf, 0);
glCompileShader(fragShader);
DepalShader *depal = new DepalShader();

CheckShaderCompileSuccess(fragShader, buffer);
std::vector<GLRProgram::Semantic> semantics;
semantics.push_back({ 0, "a_position" });
semantics.push_back({ 1, "a_texcoord0" });

GLuint program = glCreateProgram();
glAttachShader(program, vertexShader_);
glAttachShader(program, fragShader);

glBindAttribLocation(program, 0, "a_position");
glBindAttribLocation(program, 1, "a_texcoord0");
std::vector<GLRProgram::UniformLocQuery> queries;
queries.push_back({ &depal->u_tex, "tex" });
queries.push_back({ &depal->u_pal, "pal" });

glLinkProgram(program);
glUseProgram(program);
std::vector<GLRProgram::Initializer> initializer;
initializer.push_back({ &depal->u_tex, 0 });
initializer.push_back({ &depal->u_pal, 3 });

GLint u_tex = glGetUniformLocation(program, "tex");
GLint u_pal = glGetUniformLocation(program, "pal");
std::vector<GLRShader *> shaders{ vertexShader_, fragShader };

glUniform1i(u_tex, 0);
glUniform1i(u_pal, 3);
GLRProgram *program = render_->CreateProgram(shaders, semantics, queries, initializer, false);

DepalShader *depal = new DepalShader();
depal->program = program;
depal->fragShader = fragShader;
depal->code = buffer;
depal->a_position = 0;
depal->a_texcoord0 = 1;
cache_[id] = depal;

GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE) {
GLint bufLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
if (bufLength) {
char* errorbuf = new char[bufLength];
glGetProgramInfoLog(program, bufLength, NULL, errorbuf);
#ifdef SHADERLOG
OutputDebugStringUTF8(buffer);
OutputDebugStringUTF8(errorbuf);
#endif
ERROR_LOG(G3D, "Could not link program:\n %s \n\n %s", errorbuf, buf);
delete[] errorbuf; // we're dead!
}

// Since it failed, let's mark it in the cache so we don't keep retrying.
// That will only make it slower.
depal->program = 0;

// We will delete the shader later in Clear().
glDeleteProgram(program);
} else {
depal->a_position = glGetAttribLocation(program, "a_position");
depal->a_texcoord0 = glGetAttribLocation(program, "a_texcoord0");
}

delete[] buffer;
return depal->program ? depal : nullptr;
}
Expand Down
17 changes: 11 additions & 6 deletions GPU/GLES/DepalettizeShaderGLES.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,38 @@

#include "Common/CommonTypes.h"
#include "gfx/gl_common.h"
#include "thin3d/thin3d.h"
#include "thin3d/GLRenderManager.h"
#include "GPU/ge_constants.h"
#include "GPU/Common/ShaderCommon.h"
#include "GPU/Common/DepalettizeShaderCommon.h"

class DepalShader {
public:
GLuint program;
GLuint fragShader;
GLRProgram *program;
GLRShader *fragShader;
GLint a_position;
GLint a_texcoord0;
GLint u_tex;
GLint u_pal;
std::string code;
};

class DepalTexture {
public:
GLuint texture;
GLRTexture *texture;
int lastFrame;
};

// Caches both shaders and palette textures.
class DepalShaderCacheGLES : public DepalShaderCacheCommon {
public:
DepalShaderCacheGLES();
DepalShaderCacheGLES(Draw::DrawContext *draw);
~DepalShaderCacheGLES();

// This also uploads the palette and binds the correct texture.
DepalShader *GetDepalettizeShader(uint32_t clutMode, GEBufferFormat pixelFormat);
GLuint GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut);
GLRTexture *GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut);
void Clear();
void Decimate();
std::vector<std::string> DebugGetShaderIDs(DebugShaderType type);
Expand All @@ -55,9 +59,10 @@ class DepalShaderCacheGLES : public DepalShaderCacheCommon {
private:
bool CreateVertexShader();

GLRenderManager *render_;
bool useGL3_;
bool vertexShaderFailed_;
GLuint vertexShader_;
GLRShader *vertexShader_;
std::map<u32, DepalShader *> cache_;
std::map<u32, DepalTexture *> texCache_;
};
Expand Down
2 changes: 1 addition & 1 deletion GPU/GLES/DrawEngineGLES.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class DrawEngineGLES : public DrawEngineCommon {
void FinishDeferred() {
if (!numDrawCalls)
return;
DecodeVerts(decoded);
DoFlush();
}

bool IsCodePtrVertexDecoder(const u8 *ptr) const;
Expand Down
38 changes: 12 additions & 26 deletions GPU/GLES/FragmentTestCacheGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.

#include "thin3d/thin3d.h"
#include "gfx/gl_debug_log.h"
#include "Core/Config.h"
#include "GPU/GLES/FragmentTestCacheGLES.h"
Expand All @@ -26,7 +27,8 @@
static const int FRAGTEST_TEXTURE_OLD_AGE = 307;
static const int FRAGTEST_DECIMATION_INTERVAL = 113;

FragmentTestCacheGLES::FragmentTestCacheGLES() : textureCache_(NULL), lastTexture_(0), decimationCounter_(0) {
FragmentTestCacheGLES::FragmentTestCacheGLES(Draw::DrawContext *draw) {
render_ = (GLRenderManager *)draw->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
scratchpad_ = new u8[256 * 4];
}

Expand All @@ -51,17 +53,12 @@ void FragmentTestCacheGLES::BindTestTexture(GLenum unit) {
const auto cached = cache_.find(id);
if (cached != cache_.end()) {
cached->second.lastFrame = gpuStats.numFlips;
GLuint tex = cached->second.texture;
GLRTexture *tex = cached->second.texture;
if (tex == lastTexture_) {
// Already bound, hurray.
return;
}
CHECK_GL_ERROR_IF_DEBUG();
glActiveTexture(unit);
glBindTexture(GL_TEXTURE_2D, tex);
// Always return to the default.
glActiveTexture(GL_TEXTURE0);
CHECK_GL_ERROR_IF_DEBUG();
render_->BindTexture(unit, tex);
lastTexture_ = tex;
return;
}
Expand All @@ -79,13 +76,9 @@ void FragmentTestCacheGLES::BindTestTexture(GLenum unit) {
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 = CreateTestTexture(funcs, refs, masks, valid);
// Always return to the default.
glActiveTexture(GL_TEXTURE0);
GLRTexture *tex = CreateTestTexture(funcs, refs, masks, valid);
lastTexture_ = tex;

render_->BindTexture(unit, tex);
FragmentTestTexture item;
item.lastFrame = gpuStats.numFlips;
item.texture = tex;
Expand All @@ -106,7 +99,7 @@ FragmentTestID FragmentTestCacheGLES::GenerateTestID() const {
return id;
}

GLuint FragmentTestCacheGLES::CreateTestTexture(const GEComparison funcs[4], const u8 refs[4], const u8 masks[4], const bool valid[4]) {
GLRTexture *FragmentTestCacheGLES::CreateTestTexture(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.

Expand Down Expand Up @@ -146,22 +139,15 @@ GLuint FragmentTestCacheGLES::CreateTestTexture(const GEComparison funcs[4], con
}
}

GLuint tex = textureCache_->AllocTextureName();
glBindTexture(GL_TEXTURE_2D, tex);
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);

GLRTexture *tex = render_->CreateTexture(GL_TEXTURE_2D);
render_->TextureImage(tex, 0, 256, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, scratchpad_);
return tex;
}

void FragmentTestCacheGLES::Clear(bool deleteThem) {
if (deleteThem) {
for (auto tex = cache_.begin(); tex != cache_.end(); ++tex) {
glDeleteTextures(1, &tex->second.texture);
render_->DeleteTexture(tex->second.texture);
}
}
cache_.clear();
Expand All @@ -172,7 +158,7 @@ void FragmentTestCacheGLES::Decimate() {
if (--decimationCounter_ <= 0) {
for (auto tex = cache_.begin(); tex != cache_.end(); ) {
if (tex->second.lastFrame + FRAGTEST_TEXTURE_OLD_AGE < gpuStats.numFlips) {
glDeleteTextures(1, &tex->second.texture);
render_->DeleteTexture(tex->second.texture);
cache_.erase(tex++);
} else {
++tex;
Expand Down
Loading

0 comments on commit bd68181

Please sign in to comment.