diff --git a/src/main/cpp/gl/DSA/DSAWrapper.cpp b/src/main/cpp/gl/DSA/DSAWrapper.cpp index 04fd14f..2c89129 100644 --- a/src/main/cpp/gl/DSA/DSAWrapper.cpp +++ b/src/main/cpp/gl/DSA/DSAWrapper.cpp @@ -73,7 +73,10 @@ void temporarilyBindBuffer(GLuint bufferID, GLenum target = GL_ARRAY_BUFFER) { GLenum bindingQuery = GetBindingQuery(target); GLint prev = 0; glGetIntegerv(bindingQuery, &prev); - + if (prev == bufferID) { + bufferBindingStack[target].push_back(-1); + return; + } bufferBindingStack[target].push_back(static_cast(prev)); LOG_D("[DSA] [TempBind] target=0x%X, prev=%u -> bind=%u", target, prev, bufferID); @@ -91,6 +94,11 @@ void restoreTemporaryBufferBinding(GLenum target = GL_ARRAY_BUFFER) { GLuint toRestore = it->second.back(); it->second.pop_back(); + if (toRestore == static_cast(-1)) { + LOG_D("[DSA] [Restore] target=0x%X, no binding to restore", target); + return; + } + LOG_D("[DSA] [Restore] target=0x%X, bind back to %u", target, toRestore); CHECK_GL_ERROR; glBindBuffer(target, toRestore); @@ -374,6 +382,10 @@ void temporarilyBindFramebuffer(GLuint framebufferID, GLenum target = GL_DRAW_FR GLenum bindingQuery = GetBindingQuery(target); GLint prev = 0; glGetIntegerv(bindingQuery, &prev); + if (prev == framebufferID) { + framebufferBindingStack[target].push_back(-1); + return; + } framebufferBindingStack[target].push_back(static_cast(prev)); LOG_D("[DSA] [TempBind] target=0x%X, prev=%u -> bind=%u", target, prev, framebufferID); CHECK_GL_ERROR; @@ -388,6 +400,10 @@ void restoreTemporaryFramebufferBinding(GLenum target = GL_DRAW_FRAMEBUFFER) { } GLuint toRestore = it->second.back(); it->second.pop_back(); + if (toRestore == static_cast(-1)) { + LOG_D("[DSA] [Restore] target=0x%X, no binding to restore", target); + return; + } LOG_D("[DSA] [Restore] target=0x%X, bind back to %u", target, toRestore); CHECK_GL_ERROR; glBindFramebuffer(target, toRestore); @@ -674,6 +690,10 @@ void temporarilyBindRenderbuffer(GLuint renderbufferID) { GLenum bindingQuery = GetBindingQuery(GL_RENDERBUFFER); GLint prev = 0; glGetIntegerv(bindingQuery, &prev); + if (prev == renderbufferID) { + renderbufferBindingStack[GL_RENDERBUFFER].push_back(-1); + return; + } renderbufferBindingStack[GL_RENDERBUFFER].push_back(static_cast(prev)); LOG_D("[DSA] [TempBind] prev=%u -> bind=%u", prev, renderbufferID); CHECK_GL_ERROR; @@ -688,6 +708,10 @@ void restoreTemporaryRenderbufferBinding() { } GLuint toRestore = it->second.back(); it->second.pop_back(); + if (toRestore == static_cast(-1)) { + LOG_D("[DSA] [Restore] no binding to restore for GL_RENDERBUFFER"); + return; + } LOG_D("[DSA] [Restore] bind back to %u", toRestore); CHECK_GL_ERROR; glBindRenderbuffer(GL_RENDERBUFFER, toRestore); @@ -776,6 +800,10 @@ void temporarilyBindTexture(GLuint textureID, GLenum possibleTarget = 0) { GLenum bindingQuery = GetBindingQuery(target, true); GLint prev = 0; glGetIntegerv(bindingQuery, &prev); + if (prev == static_cast(textureID)) { + textureBindingStack[target].push_back(-1); + return; + } textureBindingStack[target].push_back(static_cast(prev)); LOG_D("[DSA] [TempBind] target=0x%X, prev=%u -> bind=%u", target, prev, textureID); CHECK_GL_ERROR; @@ -793,6 +821,10 @@ void restoreTemporaryTextureBinding(GLuint textureID, GLenum possibleTarget = 0) GLuint toRestore = stackIt->second.back(); stackIt->second.pop_back(); + if (toRestore == static_cast(-1)) { + LOG_D("[DSA] [Restore] target=0x%X, no binding to restore", target); + return; + } LOG_D("[DSA] [Restore] target=0x%X, bind back to %u", target, toRestore); CHECK_GL_ERROR; glBindTexture(target, toRestore); @@ -1108,9 +1140,10 @@ void glGetTextureParameteriv(GLuint texture, GLenum pname, GLint* params) { } // vertex array -static thread_local GLint prevVAO = 0; +static thread_local GLint prevVAO = -1; void temporarilyBindVertexArray(GLint vaoID) { if (prevVAO == vaoID) { + prevVAO = -1; return; } LOG_D("[DSA] [TempBind] VAO: %u -> bind=%u", prevVAO, vaoID); @@ -1120,14 +1153,14 @@ void temporarilyBindVertexArray(GLint vaoID) { CHECK_GL_ERROR_NO_INIT; } void restoreTemporaryVertexArrayBinding() { - if (prevVAO == 0) { + if (prevVAO == -1) { return; } LOG_D("[DSA] [Restore] VAO: bind back to %u", prevVAO); CHECK_GL_ERROR; glBindVertexArray(prevVAO); CHECK_GL_ERROR_NO_INIT; - prevVAO = 0; + prevVAO = -1; } void glCreateVertexArrays(GLsizei n, GLuint* arrays) { @@ -1503,6 +1536,10 @@ static void pushXFB(GLuint xfb) { LOG_D("[DSA] pushXFB, xfb: %u", xfb); GLint prev = 0; glGetIntegerv(GL_TRANSFORM_FEEDBACK_BINDING, &prev); + if (xfb == prev) { + g_xfbBindingStack.push_back(-1); + return; + } g_xfbBindingStack.push_back(prev); glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb); CHECK_GL_ERROR; @@ -1513,6 +1550,10 @@ static void popXFB() { assert(!g_xfbBindingStack.empty()); GLint prev = g_xfbBindingStack.back(); g_xfbBindingStack.pop_back(); + if (prev == -1) { + LOG_D("[DSA] No previous XFB binding to restore"); + return; + } glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, (GLuint)prev); CHECK_GL_ERROR; } diff --git a/src/main/cpp/gl/buffer.cpp b/src/main/cpp/gl/buffer.cpp index 3ba7e61..24608f1 100644 --- a/src/main/cpp/gl/buffer.cpp +++ b/src/main/cpp/gl/buffer.cpp @@ -233,6 +233,28 @@ void glBindBuffer(GLenum target, GLuint buffer) { CHECK_GL_ERROR } +struct atomic_buffer { + GLuint id; + GLsizeiptr size; + GLintptr offset; +}; + +static std::vector g_buffer_map_atomic_buffer_info; +static std::vector g_buffer_map_ssbo_id; // shall we use this in the future? + +void bindAllAtomicCounterAsSSBO() { + const size_t count = g_buffer_map_atomic_buffer_info.size(); + for (size_t i = 0; i < count; ++i) { + atomic_buffer buf = g_buffer_map_atomic_buffer_info[i]; + if (buf.id != 0) { + GLuint realID = find_real_buffer(buf.id); + GLES.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, realID, buf.offset, buf.size); + LOG_D("Bound atomic counter buffer %u(real: %u) as SSBO at index %zu", buf, realID, i); + } + } + +} + void glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) { LOG() LOG_D("glBindBufferRange, target = %s, index = %d, buffer = %d, offset = %p, size = %zi", glEnumToString(target), index, buffer, (void*) offset, size) @@ -254,6 +276,12 @@ void glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offs CHECK_GL_ERROR } GLES.glBindBufferRange(target, index, real_buffer, offset, size); + if (target == GL_ATOMIC_COUNTER_BUFFER) { + if (g_buffer_map_atomic_buffer_info.empty()) { + g_buffer_map_atomic_buffer_info.resize(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, {}); + } + g_buffer_map_atomic_buffer_info[index] = { buffer, size, offset }; + } CHECK_GL_ERROR } @@ -278,6 +306,12 @@ void glBindBufferBase(GLenum target, GLuint index, GLuint buffer) { CHECK_GL_ERROR } GLES.glBindBufferBase(target, index, real_buffer); + if (target == GL_SHADER_STORAGE_BUFFER) { + if (g_buffer_map_ssbo_id.empty()) { + g_buffer_map_ssbo_id.resize(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, 0); + } + g_buffer_map_ssbo_id[index] = buffer; + } CHECK_GL_ERROR } diff --git a/src/main/cpp/gl/drawing.cpp b/src/main/cpp/gl/drawing.cpp index abd778d..bc1f514 100644 --- a/src/main/cpp/gl/drawing.cpp +++ b/src/main/cpp/gl/drawing.cpp @@ -132,30 +132,7 @@ void glUniform1i(GLint location, GLint v0) { CHECK_GL_ERROR } -void bindAllAtomicCounterAsSSBO() { - GLint maxBindings = 0; - GLES.glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &maxBindings); - if (maxBindings <= 0) { - LOG_W("No atomic counter buffer bindings available, maxBindings: %d", maxBindings); - return; - } - - std::vector buffers(maxBindings, 0); - - for (GLint i = 0; i < maxBindings; ++i) { - GLES.glGetIntegeri_v(GL_ATOMIC_COUNTER_BUFFER_BINDING, i, reinterpret_cast(&buffers[i])); - } - - for (GLint i = 0; i < maxBindings; ++i) { - GLuint buf = buffers[i]; - if (buf != 0) { - GLES.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, buf); - } - } - - LOG_D("Bound %d atomic counter buffers as SSBOs", maxBindings); -} - +void bindAllAtomicCounterAsSSBO(); void glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) { LOG() LOG_D("glDispatchCompute, num_groups_x: %d, num_groups_y: %d, num_groups_z: %d", diff --git a/src/main/cpp/gl/glsl/glsl_for_es.cpp b/src/main/cpp/gl/glsl/glsl_for_es.cpp index a22f8ed..007f6ab 100644 --- a/src/main/cpp/gl/glsl/glsl_for_es.cpp +++ b/src/main/cpp/gl/glsl/glsl_for_es.cpp @@ -563,7 +563,7 @@ bool process_non_opaque_atomic_to_ssbo(std::string& source) { std::string matched_stmt = it->str(); result += matched_stmt; - result += "\n memoryBarrierBuffer();"; + result += "\n memoryBarrierBuffer();barrier();"; processed_positions.insert(start_pos); last_pos = end_pos;