GLES: Show post-shader compile errors to user.

This commit is contained in:
Unknown W. Brackets 2018-04-01 19:46:26 -07:00
parent 98d4131003
commit c6ef547176
4 changed files with 65 additions and 28 deletions

View file

@ -163,9 +163,7 @@ void FramebufferManagerGLES::CompilePostShader() {
semantics.push_back({ 0, "a_position" });
semantics.push_back({ 1, "a_texcoord0" });
postShaderProgram_ = render_->CreateProgram(shaders, semantics, queries, inits, false);
for (auto iter : shaders) {
render_->DeleteShader(iter);
}
postShaderModules_ = shaders;
} else {
ERROR_LOG(FRAMEBUF, "Failed to translate post shader!");
}
@ -176,31 +174,7 @@ void FramebufferManagerGLES::CompilePostShader() {
// DO NOT turn this into a report, as it will pollute our logs with all kinds of
// user shader experiments.
ERROR_LOG(FRAMEBUF, "Failed to build post-processing program from %s and %s!\n%s", shaderInfo->vertexShaderFile.c_str(), shaderInfo->fragmentShaderFile.c_str(), errorString.c_str());
// let's show the first line of the error string as an OSM.
std::set<std::string> blacklistedLines;
// These aren't useful to show, skip to the first interesting line.
blacklistedLines.insert("Fragment shader failed to compile with the following errors:");
blacklistedLines.insert("Vertex shader failed to compile with the following errors:");
blacklistedLines.insert("Compile failed.");
blacklistedLines.insert("");
std::string firstLine;
size_t start = 0;
for (size_t i = 0; i < errorString.size(); i++) {
if (errorString[i] == '\n') {
firstLine = errorString.substr(start, i - start);
if (blacklistedLines.find(firstLine) == blacklistedLines.end()) {
break;
}
start = i + 1;
firstLine.clear();
}
}
if (!firstLine.empty()) {
host->NotifyUserMessage("Post-shader error: " + firstLine + "...", 10.0f, 0xFF3090FF);
} else {
host->NotifyUserMessage("Post-shader error, see log for details", 10.0f, 0xFF3090FF);
}
ShowPostShaderError(errorString);
usePostShader_ = false;
} else {
usePostShader_ = true;
@ -211,6 +185,36 @@ void FramebufferManagerGLES::CompilePostShader() {
}
}
void FramebufferManagerGLES::ShowPostShaderError(const std::string &errorString) {
// let's show the first line of the error string as an OSM.
std::set<std::string> blacklistedLines;
// These aren't useful to show, skip to the first interesting line.
blacklistedLines.insert("Fragment shader failed to compile with the following errors:");
blacklistedLines.insert("Vertex shader failed to compile with the following errors:");
blacklistedLines.insert("Compile failed.");
blacklistedLines.insert("");
std::string firstLine;
size_t start = 0;
for (size_t i = 0; i < errorString.size(); i++) {
if (errorString[i] == '\n' && i == start) {
start = i + 1;
} else if (errorString[i] == '\n') {
firstLine = errorString.substr(start, i - start);
if (blacklistedLines.find(firstLine) == blacklistedLines.end()) {
break;
}
start = i + 1;
firstLine.clear();
}
}
if (!firstLine.empty()) {
host->NotifyUserMessage("Post-shader error: " + firstLine + "...", 10.0f, 0xFF3090FF);
} else {
host->NotifyUserMessage("Post-shader error, see log for details", 10.0f, 0xFF3090FF);
}
}
void FramebufferManagerGLES::Bind2DShader() {
render_->BindProgram(draw2dprogram_);
}
@ -220,6 +224,30 @@ void FramebufferManagerGLES::BindPostShader(const PostShaderUniforms &uniforms)
if (!postShaderProgram_) {
CompileDraw2DProgram();
}
bool failed = false;
std::string errorMessage;
for (size_t i = 0; i < postShaderModules_.size(); ++i) {
auto &shader = postShaderModules_[i];
if (shader->failed) {
failed = true;
errorMessage += shader->error + "\n";
}
if (shader->valid || shader->failed) {
render_->DeleteShader(shader);
postShaderModules_.erase(postShaderModules_.begin() + i);
// Check this index again.
i--;
}
}
if (failed) {
ShowPostShaderError(errorMessage);
// Show stuff if possible in an upcoming frame.
usePostShader_ = false;
}
render_->BindProgram(postShaderProgram_);
if (deltaLoc_ != -1)
render_->SetUniformF(&deltaLoc_, 2, uniforms.texelDelta);
@ -286,6 +314,11 @@ void FramebufferManagerGLES::DestroyDeviceObjects() {
render_->DeleteProgram(postShaderProgram_);
postShaderProgram_ = nullptr;
}
// Will usually be clear already.
for (auto iter : postShaderModules_) {
render_->DeleteShader(iter);
}
postShaderModules_.clear();
if (drawPixelsTex_) {
render_->DeleteTexture(drawPixelsTex_);
drawPixelsTex_ = 0;

View file

@ -83,6 +83,7 @@ private:
void MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height, float &u1, float &v1) override;
void Bind2DShader() override;
void BindPostShader(const PostShaderUniforms &uniforms) override;
void ShowPostShaderError(const std::string &errorMessage);
void CompileDraw2DProgram();
void CompilePostShader();
@ -100,6 +101,7 @@ private:
u32 convBufSize_ = 0;
GLRProgram *draw2dprogram_ = nullptr;
GLRProgram *postShaderProgram_ = nullptr;
std::vector<GLRShader *> postShaderModules_;
GLRProgram *stencilUploadProgram_ = nullptr;
int u_stencilUploadTex = -1;

View file

@ -215,6 +215,7 @@ void GLQueueRunner::RunInitSteps(const std::vector<GLRInitStep> &steps) {
#endif
step.create_shader.shader->valid = false;
step.create_shader.shader->failed = true;
step.create_shader.shader->error = infoLog;
}
// Before we throw away the code, attach it to the shader for debugging.
step.create_shader.shader->code = code;

View file

@ -79,6 +79,7 @@ public:
bool failed = false;
std::string desc;
std::string code;
std::string error;
};
class GLRProgram {