Skip to content

Commit

Permalink
Refactor to reuse more code.
Browse files Browse the repository at this point in the history
  • Loading branch information
unknownbrackets committed Nov 29, 2015
1 parent e7f237e commit 17675ca
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 278 deletions.
108 changes: 31 additions & 77 deletions GPU/GLES/DepalettizeShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,25 +193,7 @@ void DepalShaderCache::Decimate() {
}
}

DepalShader *DepalShaderCache::GetDepalettizeShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
u32 id = GenerateShaderID(clutFormat, pixelFormat);

auto shader = cache_.find(id);
if (shader != cache_.end()) {
return shader->second;
}

if (vertexShader_ == 0) {
if (!CreateVertexShader()) {
// The vertex shader failed, no need to bother trying the fragment.
return nullptr;
}
}

char *buffer = new char[2048];

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

void DepalShaderCache::CreateFragShader(DepalShader *depal, char *buffer) {
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);

const char *buf = buffer;
Expand All @@ -232,14 +214,14 @@ DepalShader *DepalShaderCache::GetDepalettizeShader(GEPaletteFormat clutFormat,

GLint u_tex = glGetUniformLocation(program, "tex");
GLint u_pal = glGetUniformLocation(program, "pal");
GLint u_offset = glGetUniformLocation(program, "u_offset");

glUniform1i(u_tex, 0);
glUniform1i(u_pal, 3);

DepalShader *depal = new DepalShader();
depal->program = program;
depal->fragShader = fragShader;
cache_[id] = depal;
depal->u_offset = u_offset;

GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
Expand Down Expand Up @@ -267,15 +249,37 @@ DepalShader *DepalShaderCache::GetDepalettizeShader(GEPaletteFormat clutFormat,
depal->a_position = glGetAttribLocation(program, "a_position");
depal->a_texcoord0 = glGetAttribLocation(program, "a_texcoord0");
}
}

DepalShader *DepalShaderCache::GetDepalettizeShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat) {
u32 id = GenerateShaderID(clutFormat, pixelFormat);

auto shader = cache_.find(id);
if (shader != cache_.end()) {
return shader->second;
}

if (vertexShader_ == 0) {
if (!CreateVertexShader()) {
// The vertex shader failed, no need to bother trying the fragment.
return nullptr;
}
}

char *buffer = new char[2048];
GenerateDepalShader(buffer, pixelFormat, useGL3_ ? GLSL_300 : GLSL_140);

DepalShader *depal = new DepalShader();
CreateFragShader(depal, buffer);

delete[] buffer;
return depal->program ? depal : nullptr;
}

IndexedShader *DepalShaderCache::GetIndexedShader() {
DepalShader *DepalShaderCache::GetIndexedShader() {
if (indexedShader_.program != 0) {
if (indexedShader_.program == -1) {
// Previously failed.
// Previously failed. Don't try again.
return nullptr;
}
return &indexedShader_;
Expand All @@ -291,62 +295,12 @@ IndexedShader *DepalShaderCache::GetIndexedShader() {
char *buffer = new char[2048];
GenerateIndexedShader(buffer, useGL3_ ? GLSL_300 : GLSL_140);

GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);

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

CheckShaderCompileSuccess(fragShader, buffer);

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

glBindAttribLocation(program, 0, "a_position");
glBindAttribLocation(program, 1, "a_texcoord0");

glLinkProgram(program);
glUseProgram(program);

GLint u_tex = glGetUniformLocation(program, "tex");
GLint u_pal = glGetUniformLocation(program, "pal");
GLint u_offset = glGetUniformLocation(program, "u_offset");

glUniform1i(u_tex, 0);
glUniform1i(u_pal, 3);

indexedShader_.program = program;
indexedShader_.fragShader = fragShader;
indexedShader_.u_offset = u_offset;

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.
CreateFragShader(&indexedShader_, buffer);
if (indexedShader_.program == 0) {
// So that we know not to try again next time.
indexedShader_.program = -1;

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

delete[] buffer;
return indexedShader_.program ? &indexedShader_ : nullptr;
return indexedShader_.program != 0 && indexedShader_.program != -1 ? &indexedShader_ : nullptr;
}
21 changes: 7 additions & 14 deletions GPU/GLES/DepalettizeShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@

class DepalShader {
public:
DepalShader() : program(0), fragShader(0) {
}

GLuint program;
GLuint fragShader;
GLint a_position;
GLint a_texcoord0;
GLint u_offset;
};

class DepalTexture {
Expand All @@ -35,18 +39,6 @@ class DepalTexture {
int lastFrame;
};

class IndexedShader {
public:
IndexedShader() : program(0), fragShader(0) {
}

GLuint program;
GLuint fragShader;
GLint a_position;
GLint a_texcoord0;
GLint u_offset;
};

// Caches both shaders and palette textures.
class DepalShaderCache {
public:
Expand All @@ -56,19 +48,20 @@ class DepalShaderCache {
// This also uploads the palette and binds the correct texture.
DepalShader *GetDepalettizeShader(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat);
GLuint GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut);
IndexedShader *GetIndexedShader();
DepalShader *GetIndexedShader();
void Clear();
void Decimate();

private:
u32 GenerateShaderID(GEPaletteFormat clutFormat, GEBufferFormat pixelFormat);
bool CreateVertexShader();
void CreateFragShader(DepalShader *depal, char *buffer);

bool useGL3_;
bool vertexShaderFailed_;
GLuint vertexShader_;
std::map<u32, DepalShader *> cache_;
std::map<u32, DepalTexture *> texCache_;
IndexedShader indexedShader_;
DepalShader indexedShader_;
};

Loading

0 comments on commit 17675ca

Please sign in to comment.