mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-08-31 09:45:24 +02:00
This is a leftover from the old "native" library. Its only users are the Win32 GE debugger's preview windows, which call glsl_create_source/destroy/bind/unbind and read four locations off the struct. Everything else was dead: glsl_create was declared but never defined anywhere, which made the entire file-loading and auto-reload half of glsl_recompile unreachable (glsl_create_source always passes empty filenames), along with the mtime fields, AutoCharArrayBuf and the VFS/stat includes. glsl_attrib_loc, glsl_uniform_loc and glsl_get_program had no callers, and the active_programs set was written and never read. The unused convenience locations cost a glGetUniformLocation round trip each at link time. The bug: the vertex shader was leaked when its own compile failed - the fragment path right below it already deleted it correctly. Failed links leaked the program object too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vd8ntC2brCUtCrDJMqLbs8
119 lines
3.3 KiB
C++
119 lines
3.3 KiB
C++
#include <cstdio>
|
|
#include <cstring>
|
|
|
|
#include "Common/GPU/OpenGL/GLSLProgram.h"
|
|
|
|
#include "Common/Log.h"
|
|
|
|
static bool CompileShader(const char *source, GLuint shader, const char *stageName, std::string *error_message) {
|
|
glShaderSource(shader, 1, &source, nullptr);
|
|
glCompileShader(shader);
|
|
GLint success;
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
|
if (!success) {
|
|
#define MAX_INFO_LOG_SIZE 2048
|
|
GLchar infoLog[MAX_INFO_LOG_SIZE];
|
|
GLsizei len;
|
|
glGetShaderInfoLog(shader, MAX_INFO_LOG_SIZE, &len, infoLog);
|
|
infoLog[len] = '\0';
|
|
ERROR_LOG(Log::G3D, "Error compiling %s shader!\n", stageName);
|
|
ERROR_LOG(Log::G3D, "Info log: %s\n", infoLog);
|
|
ERROR_LOG(Log::G3D, "Shader source:\n%s\n", source);
|
|
if (error_message)
|
|
*error_message = infoLog;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool glsl_compile(GLSLProgram *program, const char *vshader_src, const char *fshader_src, std::string *error_message) {
|
|
GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
|
|
if (!CompileShader(vshader_src, vsh, "vertex", error_message)) {
|
|
glDeleteShader(vsh);
|
|
return false;
|
|
}
|
|
|
|
GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
|
|
if (!CompileShader(fshader_src, fsh, "fragment", error_message)) {
|
|
glDeleteShader(vsh);
|
|
glDeleteShader(fsh);
|
|
return false;
|
|
}
|
|
|
|
GLuint prog = glCreateProgram();
|
|
glAttachShader(prog, vsh);
|
|
glAttachShader(prog, fsh);
|
|
|
|
glLinkProgram(prog);
|
|
|
|
GLint linkStatus;
|
|
glGetProgramiv(prog, GL_LINK_STATUS, &linkStatus);
|
|
if (linkStatus == GL_FALSE) {
|
|
GLint bufLength = 0;
|
|
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &bufLength);
|
|
if (bufLength) {
|
|
char *buf = new char[bufLength + 1]; // safety
|
|
glGetProgramInfoLog(prog, bufLength, nullptr, buf);
|
|
ERROR_LOG(Log::G3D, "Could not link shader program (linkstatus=%i):\n %s \n", linkStatus, buf);
|
|
if (error_message) {
|
|
*error_message = buf;
|
|
}
|
|
delete[] buf;
|
|
} else {
|
|
ERROR_LOG(Log::G3D, "Could not link shader program (linkstatus=%i). No OpenGL error log was available.", linkStatus);
|
|
if (error_message) {
|
|
*error_message = "(no error message available)";
|
|
}
|
|
}
|
|
glDeleteProgram(prog);
|
|
glDeleteShader(vsh);
|
|
glDeleteShader(fsh);
|
|
return false;
|
|
}
|
|
|
|
program->program_ = prog;
|
|
program->vsh_ = vsh;
|
|
program->fsh_ = fsh;
|
|
|
|
program->sampler0 = glGetUniformLocation(program->program_, "sampler0");
|
|
program->u_viewproj = glGetUniformLocation(program->program_, "u_viewproj");
|
|
program->a_position = glGetAttribLocation(program->program_, "a_position");
|
|
program->a_texcoord0 = glGetAttribLocation(program->program_, "a_texcoord0");
|
|
return true;
|
|
}
|
|
|
|
GLSLProgram *glsl_create_source(const char *vshader_src, const char *fshader_src, std::string *error_message) {
|
|
GLSLProgram *program = new GLSLProgram();
|
|
program->program_ = 0;
|
|
program->vsh_ = 0;
|
|
program->fsh_ = 0;
|
|
if (!glsl_compile(program, vshader_src, fshader_src, error_message)) {
|
|
ERROR_LOG(Log::G3D, "Failed compiling GLSL program from source strings");
|
|
delete program;
|
|
return nullptr;
|
|
}
|
|
return program;
|
|
}
|
|
|
|
void glsl_destroy(GLSLProgram *program) {
|
|
if (program) {
|
|
glDeleteShader(program->vsh_);
|
|
glDeleteShader(program->fsh_);
|
|
glDeleteProgram(program->program_);
|
|
} else {
|
|
ERROR_LOG(Log::G3D, "Deleting null GLSL program!");
|
|
}
|
|
delete program;
|
|
}
|
|
|
|
void glsl_bind(const GLSLProgram *program) {
|
|
if (program)
|
|
glUseProgram(program->program_);
|
|
else
|
|
glUseProgram(0);
|
|
}
|
|
|
|
void glsl_unbind() {
|
|
glUseProgram(0);
|
|
}
|