LPDIRECT3DPIXELSHADER9 DepalShaderCacheDX9::GetDepalettizePixelShader(GEBufferFormat pixelFormat) { u32 id = GenerateShaderID(pixelFormat); auto shader = cache_.find(id); if (shader != cache_.end()) { return shader->second->pixelShader; } char *buffer = new char[2048]; GenerateDepalShader(buffer, pixelFormat, HLSL_DX9); LPDIRECT3DPIXELSHADER9 pshader; std::string errorMessage; if (!CompilePixelShader(buffer, &pshader, NULL, errorMessage)) { ERROR_LOG(G3D, "Failed to compile depal pixel shader: %s\n\n%s", buffer, errorMessage.c_str()); delete[] buffer; return nullptr; } DepalShaderDX9 *depal = new DepalShaderDX9(); depal->pixelShader = pshader; cache_[id] = depal; delete[] buffer; return depal->pixelShader; }
GLuint DepalShaderCache::GetDepalettizeShader(GEBufferFormat pixelFormat) { u32 id = GenerateShaderID(pixelFormat); auto shader = cache_.find(id); if (shader != cache_.end()) { return shader->second->program; } char *buffer = new char[2048]; GenerateDepalShader(buffer, pixelFormat, 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"); glUniform1i(u_tex, 0); glUniform1i(u_pal, 1); 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! } delete[] buffer; return 0; } DepalShader *depal = new DepalShader(); depal->program = program; depal->fragShader = fragShader; cache_[id] = depal; delete[] buffer; return depal->program; }
DepalShader *DepalShaderCache::GetDepalettizeShader(GEBufferFormat pixelFormat) { u32 id = GenerateShaderID(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); 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"); glUniform1i(u_tex, 0); glUniform1i(u_pal, 3); DepalShader *depal = new DepalShader(); depal->program = program; depal->fragShader = fragShader; 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; }