From 7e3e6529630da3ad2ff562702f8aedf06302f6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 12 Dec 2017 15:32:15 +0100 Subject: [PATCH] Fix more gl-render-manager problems --- GPU/GLES/FragmentTestCacheGLES.cpp | 6 +++--- GPU/GLES/FragmentTestCacheGLES.h | 2 +- GPU/GLES/FramebufferManagerGLES.cpp | 7 +++++-- GPU/GLES/StateMappingGLES.cpp | 2 +- ext/native/thin3d/GLQueueRunner.cpp | 6 +++++- ext/native/thin3d/GLRenderManager.h | 16 +++++++++++----- 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/GPU/GLES/FragmentTestCacheGLES.cpp b/GPU/GLES/FragmentTestCacheGLES.cpp index 0228f3896e..4098186d20 100644 --- a/GPU/GLES/FragmentTestCacheGLES.cpp +++ b/GPU/GLES/FragmentTestCacheGLES.cpp @@ -37,7 +37,7 @@ FragmentTestCacheGLES::~FragmentTestCacheGLES() { delete [] scratchpad_; } -void FragmentTestCacheGLES::BindTestTexture(GLenum unit) { +void FragmentTestCacheGLES::BindTestTexture(int slot) { if (!g_Config.bFragmentTestCache) { return; } @@ -58,7 +58,7 @@ void FragmentTestCacheGLES::BindTestTexture(GLenum unit) { // Already bound, hurray. return; } - render_->BindTexture(unit, tex); + render_->BindTexture(slot, tex); lastTexture_ = tex; return; } @@ -78,7 +78,7 @@ void FragmentTestCacheGLES::BindTestTexture(GLenum unit) { GLRTexture *tex = CreateTestTexture(funcs, refs, masks, valid); lastTexture_ = tex; - render_->BindTexture(unit, tex); + render_->BindTexture(slot, tex); FragmentTestTexture item; item.lastFrame = gpuStats.numFlips; item.texture = tex; diff --git a/GPU/GLES/FragmentTestCacheGLES.h b/GPU/GLES/FragmentTestCacheGLES.h index 2b044614a3..9b6ac1d1be 100644 --- a/GPU/GLES/FragmentTestCacheGLES.h +++ b/GPU/GLES/FragmentTestCacheGLES.h @@ -65,7 +65,7 @@ public: textureCache_ = tc; } - void BindTestTexture(GLenum unit); + void BindTestTexture(int slot); void Clear(bool deleteThem = true); void Decimate(); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 1fbb7044a0..96e8ef5d7f 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -103,13 +103,16 @@ void FramebufferManagerGLES::CompileDraw2DProgram() { vs_code = ApplyGLSLPrelude(basic_vs, GL_VERTEX_SHADER); fs_code = ApplyGLSLPrelude(tex_fs, GL_FRAGMENT_SHADER); std::vector shaders; - GLRShader *vs = render_->CreateShader(GL_VERTEX_SHADER, vs_code); - GLRShader *fs = render_->CreateShader(GL_FRAGMENT_SHADER, fs_code); + shaders.push_back(render_->CreateShader(GL_VERTEX_SHADER, vs_code)); + shaders.push_back(render_->CreateShader(GL_FRAGMENT_SHADER, fs_code)); + std::vector queries; queries.push_back({ &u_draw2d_tex, "u_tex" }); std::vector initializers; initializers.push_back({ &u_draw2d_tex, 0 }); draw2dprogram_ = render_->CreateProgram(shaders, {}, queries, initializers, false); + for (auto shader : shaders) + render_->DeleteShader(shader); CompilePostShader(); } } diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index bb5af37045..11b7e79576 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -347,7 +347,7 @@ void DrawEngineGLES::ApplyDrawStateLate(bool setStencil, int stencilValue) { // Apply last, once we know the alpha params of the texture. if (gstate.isAlphaTestEnabled() || gstate.isColorTestEnabled()) { - fragmentTestCache_->BindTestTexture(GL_TEXTURE2); + fragmentTestCache_->BindTestTexture(2); } } } diff --git a/ext/native/thin3d/GLQueueRunner.cpp b/ext/native/thin3d/GLQueueRunner.cpp index cf886b25ef..0f738f2ded 100644 --- a/ext/native/thin3d/GLQueueRunner.cpp +++ b/ext/native/thin3d/GLQueueRunner.cpp @@ -53,7 +53,9 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps) { { GLRProgram *program = step.create_program.program; program->program = glCreateProgram(); + _assert_msg_(G3D, step.create_program.num_shaders > 0, "Can't create a program with zero shaders"); for (int i = 0; i < step.create_program.num_shaders; i++) { + _dbg_assert_msg_(G3D, step.create_program.shaders[i]->shader, "Can't create a program with a null shader"); glAttachShader(program->program, step.create_program.shaders[i]->shader); } @@ -141,7 +143,9 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps) { glDeleteShader(shader); shader = 0; ILOG("%s Shader compile error:\n%s", step.create_shader.stage == GL_FRAGMENT_SHADER ? "Fragment" : "Vertex", infoLog); + step.create_shader.shader->valid = false; } + step.create_shader.shader->valid = true; break; } case GLRInitStepType::CREATE_INPUT_LAYOUT: @@ -359,10 +363,10 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step) { case GLRRenderCommand::STENCILFUNC: if (c.stencilFunc.enabled) { glEnable(GL_STENCIL_TEST); + glStencilFunc(c.stencilFunc.func, c.stencilFunc.ref, c.stencilFunc.compareMask); } else { glDisable(GL_STENCIL_TEST); } - glStencilFunc(c.stencilFunc.func, c.stencilFunc.ref, c.stencilFunc.compareMask); break; case GLRRenderCommand::STENCILOP: glStencilOp(c.stencilOp.sFail, c.stencilOp.zFail, c.stencilOp.pass); diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 1e20c17827..b014302f52 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -52,6 +52,7 @@ public: } } GLuint shader = 0; + bool valid = false; }; class GLRProgram { @@ -116,7 +117,7 @@ public: class GLRBuffer { public: - GLRBuffer(GLuint target) : target_(target) {} + GLRBuffer(GLuint target, size_t size) : target_(target), size_((int)size) {} ~GLRBuffer() { if (buffer) { glDeleteBuffers(1, &buffer); @@ -124,6 +125,7 @@ public: } GLuint buffer = 0; GLuint target_; + int size_; private: }; @@ -192,7 +194,7 @@ public: GLRBuffer *CreateBuffer(GLuint target, size_t size, GLuint usage) { GLRInitStep step{ GLRInitStepType::CREATE_BUFFER }; - step.create_buffer.buffer = new GLRBuffer(target); + step.create_buffer.buffer = new GLRBuffer(target, size); step.create_buffer.size = (int)size; step.create_buffer.usage = usage; initSteps_.push_back(step); @@ -227,6 +229,7 @@ public: step.create_program.program->semantics_ = semantics; step.create_program.program->queries_ = queries; step.create_program.program->initialize_ = initalizers; + _assert_msg_(G3D, shaders.size() > 0, "Can't create a program with zero shaders"); for (int i = 0; i < shaders.size(); i++) { step.create_program.shaders[i] = shaders[i]; } @@ -283,6 +286,8 @@ public: // TODO: Maybe should be a render command instead of an init command? When possible it's better as // an init command, that's for sure. GLRInitStep step{ GLRInitStepType::BUFFER_SUBDATA }; + _dbg_assert_(G3D, offset >= 0); + _dbg_assert_(G3D, offset <= buffer->size_ - size); step.buffer_subdata.buffer = buffer; step.buffer_subdata.offset = offset; step.buffer_subdata.size = size; @@ -309,6 +314,7 @@ public: void BindTexture(int slot, GLRTexture *tex) { _dbg_assert_(G3D, curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::BINDTEXTURE }; + _dbg_assert_(G3D, slot < 16); data.texture.slot = slot; data.texture.texture = tex; curRenderStep_->commands.push_back(data); @@ -662,12 +668,12 @@ public: // This will later allow for handling overflow correctly. size_t Allocate(size_t numBytes, GLRBuffer **vkbuf) { size_t out = offset_; - offset_ += (numBytes + 3) & ~3; // Round up to 4 bytes. - - if (offset_ >= size_) { + if (offset_ + ((numBytes + 3) & ~3) >= size_) { NextBuffer(numBytes); out = offset_; offset_ += (numBytes + 3) & ~3; + } else { + offset_ += (numBytes + 3) & ~3; // Round up to 4 bytes. } *vkbuf = buffers_[buf_].buffer; return out;