mirror of
https://github.com/MobileGL-Dev/MobileGlues.git
synced 2025-09-26 04:32:47 -04:00
fix(buffer, drawing): correctly unmap buffer, fixing drawing on Mali GPU
This commit is contained in:
parent
a3aec1c09b
commit
7d80368008
@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.22.1)
|
|||||||
|
|
||||||
project("mobileglues")
|
project("mobileglues")
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
@ -30,7 +32,7 @@ add_library(${CMAKE_PROJECT_NAME} SHARED
|
|||||||
gl/texture.c
|
gl/texture.c
|
||||||
gl/drawing.c
|
gl/drawing.c
|
||||||
gl/mg.c
|
gl/mg.c
|
||||||
gl/buffer.c
|
gl/buffer.cpp
|
||||||
gl/getter.c
|
gl/getter.c
|
||||||
gl/glsl/glsl_for_es.cpp
|
gl/glsl/glsl_for_es.cpp
|
||||||
glx/lookup.c
|
glx/lookup.c
|
||||||
|
@ -3,9 +3,12 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
|
std::unordered_map<GLuint, BufferMapping> g_active_mappings;
|
||||||
|
|
||||||
static GLenum get_binding_query(GLenum target) {
|
static GLenum get_binding_query(GLenum target) {
|
||||||
switch(target) {
|
switch(target) {
|
||||||
case GL_ARRAY_BUFFER: return GL_ARRAY_BUFFER_BINDING;
|
case GL_ARRAY_BUFFER: return GL_ARRAY_BUFFER_BINDING;
|
||||||
@ -44,58 +47,55 @@ void* glMapBuffer(GLenum target, GLenum access) {
|
|||||||
}
|
}
|
||||||
void* ptr = glMapBufferRange(target, 0, buffer_size, flags);
|
void* ptr = glMapBufferRange(target, 0, buffer_size, flags);
|
||||||
if (!ptr) return NULL;
|
if (!ptr) return NULL;
|
||||||
g_active_mapping.target = target;
|
BufferMapping mapping;
|
||||||
g_active_mapping.buffer_id = (GLuint)current_buffer;
|
mapping.target = target;
|
||||||
g_active_mapping.mapped_ptr = ptr;
|
mapping.buffer_id = (GLuint)current_buffer;
|
||||||
g_active_mapping.size = buffer_size;
|
mapping.mapped_ptr = ptr;
|
||||||
g_active_mapping.flags = flags;
|
mapping.size = buffer_size;
|
||||||
g_active_mapping.is_dirty = (flags & GL_MAP_WRITE_BIT) ? GL_TRUE : GL_FALSE;
|
mapping.flags = flags;
|
||||||
|
mapping.is_dirty = (flags & GL_MAP_WRITE_BIT) ? GL_TRUE : GL_FALSE;
|
||||||
|
g_active_mappings[current_buffer] = mapping;
|
||||||
CHECK_GL_ERROR
|
CHECK_GL_ERROR
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void force_unmap(GLenum target, GLuint original_buffer) {
|
GLboolean force_unmap() {
|
||||||
GLint prev_buffer;
|
if (g_active_mappings.empty())
|
||||||
glGetIntegerv(get_binding_query(target), &prev_buffer);
|
return GL_FALSE;
|
||||||
GLuint temp_buffer;
|
|
||||||
glGenBuffers(1, &temp_buffer);
|
LOAD_GLES(glBindBuffer, void, GLenum target, GLuint buffer)
|
||||||
glBindBuffer(target, temp_buffer);
|
LOAD_GLES(glUnmapBuffer, GLboolean, GLenum target);
|
||||||
glBindBuffer(target, 0);
|
|
||||||
glDeleteBuffers(1, &temp_buffer);
|
for (auto& [buffer, binding]: g_active_mappings) {
|
||||||
if (target == GL_ARRAY_BUFFER) {
|
GLint prev_buffer = 0;
|
||||||
GLint prev_element_array;
|
GLenum binding_query = get_binding_query(binding.target);
|
||||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prev_element_array);
|
glGetIntegerv(binding_query, &prev_buffer);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_element_array);
|
gles_glBindBuffer(binding.target, binding.buffer_id);
|
||||||
} else {
|
GLboolean result = gles_glUnmapBuffer(binding.target);
|
||||||
GLint prev_array;
|
gles_glBindBuffer(binding.target, prev_buffer);
|
||||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prev_array);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, prev_array);
|
|
||||||
}
|
}
|
||||||
glBindBuffer(target, original_buffer);
|
|
||||||
|
g_active_mappings.clear();
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLboolean glUnmapBuffer(GLenum target) {
|
GLboolean glUnmapBuffer(GLenum target) {
|
||||||
LOG()
|
LOG()
|
||||||
if (g_active_mapping.mapped_ptr == NULL ||
|
|
||||||
g_active_mapping.target != target ||
|
|
||||||
g_active_mapping.buffer_id == 0) {
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint prev_buffer;
|
GLint buffer;
|
||||||
GLenum binding_query = get_binding_query(target);
|
GLenum binding_query = get_binding_query(target);
|
||||||
glGetIntegerv(binding_query, &prev_buffer);
|
glGetIntegerv(binding_query, &buffer);
|
||||||
|
|
||||||
glBindBuffer(target, g_active_mapping.buffer_id);
|
if (buffer == 0)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
LOAD_GLES(glUnmapBuffer, GLboolean, GLenum target);
|
LOAD_GLES(glUnmapBuffer, GLboolean, GLenum target);
|
||||||
GLboolean result = gles_glUnmapBuffer(target);
|
GLboolean result = gles_glUnmapBuffer(target);
|
||||||
|
|
||||||
glBindBuffer(target, prev_buffer);
|
g_active_mappings.erase(buffer);
|
||||||
|
|
||||||
memset(&g_active_mapping, 0, sizeof(BufferMapping));
|
|
||||||
CHECK_GL_ERROR
|
CHECK_GL_ERROR
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
@ -12,10 +12,14 @@
|
|||||||
#include "../gles/loader.h"
|
#include "../gles/loader.h"
|
||||||
#include "mg.h"
|
#include "mg.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GLenum target;
|
GLenum target;
|
||||||
GLuint buffer_id;
|
GLuint buffer_id;
|
||||||
void* mapped_ptr;
|
void *mapped_ptr;
|
||||||
GLsizeiptr size;
|
GLsizeiptr size;
|
||||||
GLbitfield flags;
|
GLbitfield flags;
|
||||||
GLboolean is_dirty;
|
GLboolean is_dirty;
|
||||||
@ -24,11 +28,17 @@ typedef struct {
|
|||||||
static BufferMapping g_active_mapping = {0};
|
static BufferMapping g_active_mapping = {0};
|
||||||
|
|
||||||
static GLenum get_binding_query(GLenum target);
|
static GLenum get_binding_query(GLenum target);
|
||||||
static void force_unmap(GLenum target, GLuint original_buffer);
|
|
||||||
|
GLboolean force_unmap();
|
||||||
|
|
||||||
GLAPI GLAPIENTRY GLboolean glUnmapBuffer(GLenum target);
|
GLAPI GLAPIENTRY GLboolean glUnmapBuffer(GLenum target);
|
||||||
|
|
||||||
GLAPI GLAPIENTRY void *glMapBuffer(GLenum target, GLenum access);
|
GLAPI GLAPIENTRY void *glMapBuffer(GLenum target, GLenum access);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MOBILEGLUES_BUFFER_H
|
#define MOBILEGLUES_BUFFER_H
|
||||||
|
|
||||||
#endif //MOBILEGLUES_BUFFER_H
|
#endif //MOBILEGLUES_BUFFER_H
|
||||||
|
@ -3,13 +3,14 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "drawing.h"
|
#include "drawing.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
void glMultiDrawElementsBaseVertex( GLenum mode, GLsizei *counts, GLenum type, const void * const *indices, GLsizei primcount, const GLint * basevertex) {
|
void glMultiDrawElementsBaseVertex( GLenum mode, GLsizei *counts, GLenum type, const void * const *indices, GLsizei primcount, const GLint * basevertex) {
|
||||||
LOG();
|
LOG();
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
||||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
force_unmap();
|
||||||
|
|
||||||
for (int i = 0; i < primcount; i++) {
|
for (int i = 0; i < primcount; i++) {
|
||||||
if (counts[i] > 0)
|
if (counts[i] > 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user