Feat[renderer]: changes
- Better multidraw - Fixed memory leaks in shader_wrapper - Changed basevertex to use dumb rendering mode
This commit is contained in:
parent
d074ec0b41
commit
bd89a868cc
@ -397,6 +397,7 @@ LOCAL_SRC_FILES := \
|
|||||||
framebuffer.c \
|
framebuffer.c \
|
||||||
of_buffer_copier.c \
|
of_buffer_copier.c \
|
||||||
stubs.c \
|
stubs.c \
|
||||||
|
multidraw.c \
|
||||||
vgpu_shaderconv/shaderconv.c \
|
vgpu_shaderconv/shaderconv.c \
|
||||||
unordered_map/unordered_map.c \
|
unordered_map/unordered_map.c \
|
||||||
unordered_map/int_hash.c
|
unordered_map/int_hash.c
|
||||||
|
@ -119,6 +119,35 @@ static void restore_state(GLuint element_buffer) {
|
|||||||
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, current_context->bound_buffers[get_buffer_index(GL_SHADER_STORAGE_BUFFER)]);
|
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, current_context->bound_buffers[get_buffer_index(GL_SHADER_STORAGE_BUFFER)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void glDrawElementsBaseVertex_inner(basevertex_renderer_t *renderer, GLenum mode,
|
||||||
|
GLsizei count,
|
||||||
|
GLenum type,
|
||||||
|
void *indices,
|
||||||
|
GLint basevertex,
|
||||||
|
GLuint elementbuffer) {
|
||||||
|
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, renderer->computeIndexBuffer);
|
||||||
|
es3_functions.glBufferData(GL_SHADER_STORAGE_BUFFER, count * (GLint)sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);
|
||||||
|
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, renderer->computeMetaBuffer);
|
||||||
|
data_buffer_t buffer_info;
|
||||||
|
buffer_info.baseVertex = basevertex;
|
||||||
|
buffer_info.elementCount = count;
|
||||||
|
buffer_info.inputBitWidth = type_bits(type);
|
||||||
|
es3_functions.glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data_buffer_t), &buffer_info);
|
||||||
|
es3_functions.glUseProgram(renderer->computeProgram);
|
||||||
|
|
||||||
|
uintptr_t offset = (uintptr_t)indices;
|
||||||
|
|
||||||
|
es3_functions.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, elementbuffer, (GLintptr)offset, count *
|
||||||
|
type_bytes(type));
|
||||||
|
es3_functions.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, renderer->computeIndexBuffer);
|
||||||
|
es3_functions.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, renderer->computeMetaBuffer);
|
||||||
|
es3_functions.glDispatchCompute((count + (256-1))/256, 1, 1);
|
||||||
|
|
||||||
|
es3_functions.glUseProgram(current_context->program);
|
||||||
|
es3_functions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderer->computeIndexBuffer);
|
||||||
|
es3_functions.glDrawElements(mode, count, GL_UNSIGNED_INT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void glDrawElementsBaseVertex(GLenum mode,
|
void glDrawElementsBaseVertex(GLenum mode,
|
||||||
GLsizei count,
|
GLsizei count,
|
||||||
GLenum type,
|
GLenum type,
|
||||||
@ -135,42 +164,44 @@ void glDrawElementsBaseVertex(GLenum mode,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, renderer->computeIndexBuffer);
|
glDrawElementsBaseVertex_inner(renderer, mode, count, type, indices, basevertex, elementbuffer);
|
||||||
es3_functions.glBufferData(GL_SHADER_STORAGE_BUFFER, count * (GLint)sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);
|
|
||||||
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, renderer->computeMetaBuffer);
|
|
||||||
data_buffer_t buffer_info;
|
|
||||||
buffer_info.baseVertex = basevertex;
|
|
||||||
buffer_info.elementCount = count;
|
|
||||||
buffer_info.inputBitWidth = type_bits(type);
|
|
||||||
es3_functions.glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(data_buffer_t), &buffer_info);
|
|
||||||
es3_functions.glUseProgram(renderer->computeProgram);
|
|
||||||
|
|
||||||
uintptr_t offset = (uintptr_t)indices;
|
|
||||||
|
|
||||||
es3_functions.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, elementbuffer, (GLintptr)offset, count *
|
|
||||||
type_bytes(type));
|
|
||||||
es3_functions.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, renderer->computeIndexBuffer);
|
|
||||||
es3_functions.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, renderer->computeMetaBuffer);
|
|
||||||
es3_functions.glDispatchCompute((count + (256-1))/256, 1, 1);
|
|
||||||
|
|
||||||
es3_functions.glUseProgram(current_context->program);
|
|
||||||
es3_functions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderer->computeIndexBuffer);
|
|
||||||
es3_functions.glDrawElements(mode, count, GL_UNSIGNED_INT, NULL);
|
|
||||||
|
|
||||||
restore_state(elementbuffer);
|
restore_state(elementbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*void glMultiDrawElementsBaseVertex(GLenum mode,
|
|
||||||
|
void glMultiDrawElementsBaseVertex(GLenum mode,
|
||||||
const GLsizei *count,
|
const GLsizei *count,
|
||||||
GLenum type,
|
GLenum type,
|
||||||
const void * const *indices,
|
const void * const *indices,
|
||||||
GLsizei drawcount,
|
GLsizei drawcount,
|
||||||
const GLint *basevertex) {
|
const GLint *basevertex) {
|
||||||
for(GLsizei i = 0; i < drawcount; i++) {
|
if(!current_context) return;
|
||||||
glDrawElementsBaseVertex(mode, count[i], type, (void*)indices[i], basevertex[i]);
|
basevertex_renderer_t *renderer = ¤t_context->basevertex;
|
||||||
|
if(!renderer->ready) return;
|
||||||
|
GLint elementbuffer;
|
||||||
|
es3_functions.glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elementbuffer);
|
||||||
|
if(elementbuffer == 0) {
|
||||||
|
// I am not bothered enough to implement this.
|
||||||
|
printf("tinywrapper: Base vertex draws without element buffer are not supported\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
|
for(GLsizei i = 0; i < drawcount; i++) {
|
||||||
|
glDrawElementsBaseVertex_inner(renderer, mode, count[i], type, (void*)indices[i], basevertex[i], elementbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_state(elementbuffer);
|
||||||
|
|
||||||
|
}
|
||||||
|
// TODO: Figure out how to fix the proper way of doing it
|
||||||
|
/*
|
||||||
|
static void render_out( basevertex_renderer_t *renderer, GLenum mode, GLsizei inserted_count) {
|
||||||
|
es3_functions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderer->computeIndexBuffer);
|
||||||
|
es3_functions.glUseProgram(current_context->program);
|
||||||
|
es3_functions.glDrawElements(mode, inserted_count, GL_UNSIGNED_INT, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void glMultiDrawElementsBaseVertex( GLenum mode,
|
void glMultiDrawElementsBaseVertex( GLenum mode,
|
||||||
const GLsizei *count,
|
const GLsizei *count,
|
||||||
@ -191,14 +222,14 @@ void glMultiDrawElementsBaseVertex( GLenum mode,
|
|||||||
GLsizei total_count = 0;
|
GLsizei total_count = 0;
|
||||||
for (int i = 0; i < drawcount; i++) total_count += count[i];
|
for (int i = 0; i < drawcount; i++) total_count += count[i];
|
||||||
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, renderer->computeIndexBuffer);
|
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, renderer->computeIndexBuffer);
|
||||||
es3_functions.glBufferData(GL_SHADER_STORAGE_BUFFER, total_count * 4, NULL, GL_DYNAMIC_DRAW);
|
es3_functions.glBufferData(GL_SHADER_STORAGE_BUFFER, total_count * 4, NULL, GL_STREAM_DRAW);
|
||||||
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, renderer->computeMetaBuffer);
|
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, renderer->computeMetaBuffer);
|
||||||
es3_functions.glUseProgram(renderer->computeProgram);
|
es3_functions.glUseProgram(renderer->computeProgram);
|
||||||
|
es3_functions.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 2, renderer->computeMetaBuffer, 0, sizeof(data_buffer_t));
|
||||||
data_buffer_t buffer_info;
|
data_buffer_t buffer_info;
|
||||||
buffer_info.inputBitWidth = type_bits(type);
|
buffer_info.inputBitWidth = type_bits(type);
|
||||||
GLint current_type_bytes = type_bytes(type);
|
GLint current_type_bytes = type_bytes(type);
|
||||||
GLsizei inserted_count = 0;
|
GLsizei inserted_count = 0;
|
||||||
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
|
||||||
for (int i = 0; i < drawcount; i++) {
|
for (int i = 0; i < drawcount; i++) {
|
||||||
GLsizei local_count = count[i];
|
GLsizei local_count = count[i];
|
||||||
uintptr_t local_indices = (uintptr_t)indices[i];
|
uintptr_t local_indices = (uintptr_t)indices[i];
|
||||||
@ -210,16 +241,9 @@ void glMultiDrawElementsBaseVertex( GLenum mode,
|
|||||||
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
es3_functions.glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
es3_functions.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, elementbuffer, (GLintptr)local_indices, local_count * current_type_bytes);
|
es3_functions.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, elementbuffer, (GLintptr)local_indices, local_count * current_type_bytes);
|
||||||
es3_functions.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, renderer->computeIndexBuffer, inserted_count * 4, local_count * 4);
|
es3_functions.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, renderer->computeIndexBuffer, inserted_count * 4, local_count * 4);
|
||||||
es3_functions.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 2, renderer->computeMetaBuffer, 0, sizeof(data_buffer_t));
|
|
||||||
GLint temp;
|
|
||||||
es3_functions.glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &temp);
|
|
||||||
es3_functions.glDispatchCompute((local_count + (256-1))/256, 1, 1);
|
es3_functions.glDispatchCompute((local_count + (256-1))/256, 1, 1);
|
||||||
|
|
||||||
inserted_count += local_count;
|
inserted_count += local_count;
|
||||||
}
|
}
|
||||||
es3_functions.glFlush();
|
render_out(renderer, mode, inserted_count);
|
||||||
es3_functions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderer->computeIndexBuffer);
|
|
||||||
es3_functions.glUseProgram(current_context->program);
|
|
||||||
es3_functions.glDrawElements(mode, inserted_count, GL_UNSIGNED_INT, NULL);
|
|
||||||
restore_state(elementbuffer);
|
restore_state(elementbuffer);
|
||||||
}
|
}*/
|
10
app/src/main/tinywrapper/basevertex.h
Normal file
10
app/src/main/tinywrapper/basevertex.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
//
|
||||||
|
// Created by maks on 25.04.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GL4ES_WRAPPER_BASEVERTEX_H
|
||||||
|
#define GL4ES_WRAPPER_BASEVERTEX_H
|
||||||
|
|
||||||
|
GLint type_bytes(GLenum type);
|
||||||
|
|
||||||
|
#endif //GL4ES_WRAPPER_BASEVERTEX_H
|
@ -64,6 +64,7 @@ static void init_incontext(context_t* tw_context) {
|
|||||||
}
|
}
|
||||||
basevertex_init(tw_context);
|
basevertex_init(tw_context);
|
||||||
buffer_copier_init(tw_context);
|
buffer_copier_init(tw_context);
|
||||||
|
es3_functions.glGenBuffers(1, &tw_context->multidraw_element_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) {
|
EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) {
|
||||||
|
@ -60,6 +60,7 @@ typedef struct {
|
|||||||
EGLContext phys_context;
|
EGLContext phys_context;
|
||||||
bool context_rdy;
|
bool context_rdy;
|
||||||
basevertex_renderer_t basevertex;
|
basevertex_renderer_t basevertex;
|
||||||
|
GLuint multidraw_element_buffer;
|
||||||
framebuffer_copier_t framebuffer_copier;
|
framebuffer_copier_t framebuffer_copier;
|
||||||
unordered_map* shader_map;
|
unordered_map* shader_map;
|
||||||
unordered_map* program_map;
|
unordered_map* program_map;
|
||||||
|
@ -132,28 +132,10 @@ const GLubyte* glGetString(GLenum name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void glEnable(GLenum cap) {
|
void glEnable(GLenum cap) {
|
||||||
//if(!current_context || cap == GL_DEBUG_OUTPUT) return;
|
if(!current_context || cap == GL_DEBUG_OUTPUT) return;
|
||||||
es3_functions.glEnable(cap);
|
es3_functions.glEnable(cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void glMultiDrawArrays( GLenum mode, GLint *first, GLsizei *count, GLsizei primcount )
|
|
||||||
{
|
|
||||||
if(!current_context) return;
|
|
||||||
for (int i = 0; i < primcount; i++) {
|
|
||||||
if (count[i] > 0)
|
|
||||||
es3_functions.glDrawArrays(mode, first[i], count[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void glMultiDrawElements( GLenum mode, GLsizei *count, GLenum type, const void * const *indices, GLsizei primcount )
|
|
||||||
{
|
|
||||||
if(!current_context) return;
|
|
||||||
for (int i = 0; i < primcount; i++) {
|
|
||||||
if (count[i] > 0)
|
|
||||||
es3_functions.glDrawElements(mode, count[i], type, indices[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_buffer_index(GLenum buffer) {
|
int get_buffer_index(GLenum buffer) {
|
||||||
switch (buffer) {
|
switch (buffer) {
|
||||||
case GL_ARRAY_BUFFER: return 0;
|
case GL_ARRAY_BUFFER: return 0;
|
||||||
|
43
app/src/main/tinywrapper/multidraw.c
Normal file
43
app/src/main/tinywrapper/multidraw.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// Created by maks on 25.04.2024.
|
||||||
|
//
|
||||||
|
#include <proc.h>
|
||||||
|
#include <egl.h>
|
||||||
|
#include "basevertex.h"
|
||||||
|
void glMultiDrawArrays( GLenum mode, GLint *first, GLsizei *count, GLsizei primcount )
|
||||||
|
{
|
||||||
|
// We'd need to merge each buffer attached to the VBO to properly achieve this. Nuh-uh. Aint no way im doin allat
|
||||||
|
if(!current_context) return;
|
||||||
|
for (int i = 0; i < primcount; i++) {
|
||||||
|
if (count[i] > 0)
|
||||||
|
es3_functions.glDrawArrays(mode, first[i], count[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glMultiDrawElements( GLenum mode, GLsizei *count, GLenum type, const void * const *indices, GLsizei primcount )
|
||||||
|
{
|
||||||
|
if(!current_context) return;
|
||||||
|
GLint elementbuffer;
|
||||||
|
es3_functions.glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elementbuffer);
|
||||||
|
es3_functions.glBindBuffer(GL_COPY_WRITE_BUFFER, current_context->multidraw_element_buffer);
|
||||||
|
GLsizei total = 0, offset = 0, typebytes = type_bytes(type);
|
||||||
|
for (GLsizei i = 0; i < primcount; i++) {
|
||||||
|
total += count[i];
|
||||||
|
}
|
||||||
|
es3_functions.glBufferData(GL_COPY_WRITE_BUFFER, total*typebytes, NULL, GL_STREAM_DRAW);
|
||||||
|
for (GLsizei i = 0; i < primcount; i++) {
|
||||||
|
GLsizei icount = count[i];
|
||||||
|
if(icount == 0) continue;
|
||||||
|
icount *= typebytes;
|
||||||
|
if(elementbuffer != 0) {
|
||||||
|
es3_functions.glCopyBufferSubData(GL_ELEMENT_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, (GLintptr)indices[i], offset, icount);
|
||||||
|
}else {
|
||||||
|
es3_functions.glBufferSubData(GL_COPY_WRITE_BUFFER, offset, icount, indices[i]);
|
||||||
|
}
|
||||||
|
offset += icount;
|
||||||
|
}
|
||||||
|
es3_functions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, current_context->multidraw_element_buffer);
|
||||||
|
es3_functions.glDrawElements(mode, total, type, 0);
|
||||||
|
if(elementbuffer != 0) es3_functions.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
|
||||||
|
|
||||||
|
}
|
@ -95,15 +95,20 @@ void glLinkProgram(GLuint program) {
|
|||||||
insert_fragout_pos(new_source, colorbind, i);
|
insert_fragout_pos(new_source, colorbind, i);
|
||||||
changesMade = true;
|
changesMade = true;
|
||||||
}
|
}
|
||||||
if(!changesMade) goto fallthrough;
|
if(!changesMade) {
|
||||||
|
free(new_source);
|
||||||
|
goto fallthrough;
|
||||||
|
}
|
||||||
const GLchar* const_source = (const GLchar*)new_source;
|
const GLchar* const_source = (const GLchar*)new_source;
|
||||||
GLuint patched_shader = es3_functions.glCreateShader(GL_FRAGMENT_SHADER);
|
GLuint patched_shader = es3_functions.glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
if(patched_shader == 0) {
|
if(patched_shader == 0) {
|
||||||
|
free(new_source);
|
||||||
printf("tinywrapper: failed to initialize patched shader\n");
|
printf("tinywrapper: failed to initialize patched shader\n");
|
||||||
goto fallthrough;
|
goto fallthrough;
|
||||||
}
|
}
|
||||||
es3_functions.glShaderSource(patched_shader, 1, &const_source, NULL);
|
es3_functions.glShaderSource(patched_shader, 1, &const_source, NULL);
|
||||||
es3_functions.glCompileShader(patched_shader);
|
es3_functions.glCompileShader(patched_shader);
|
||||||
|
free(new_source);
|
||||||
GLint compileStatus;
|
GLint compileStatus;
|
||||||
es3_functions.glGetShaderiv(patched_shader, GL_COMPILE_STATUS, &compileStatus);
|
es3_functions.glGetShaderiv(patched_shader, GL_COMPILE_STATUS, &compileStatus);
|
||||||
if(compileStatus != GL_TRUE) {
|
if(compileStatus != GL_TRUE) {
|
||||||
@ -167,7 +172,7 @@ void glShaderSource(GLuint shader, GLsizei count, const GLchar *const*string, co
|
|||||||
|
|
||||||
#undef SRC_LEN
|
#undef SRC_LEN
|
||||||
GLchar* new_source = optimize_shader(target_string, shader_info->shader_type == GL_VERTEX_SHADER, 330, 300);
|
GLchar* new_source = optimize_shader(target_string, shader_info->shader_type == GL_VERTEX_SHADER, 330, 300);
|
||||||
printf("\n\n\nShader Result\n%s\n\n\n", new_source);
|
//printf("\n\n\nShader Result\n%s\n\n\n", new_source);
|
||||||
if(shader_info->source != NULL) free((void*)shader_info->source);
|
if(shader_info->source != NULL) free((void*)shader_info->source);
|
||||||
shader_info->source = new_source;
|
shader_info->source = new_source;
|
||||||
es3_functions.glShaderSource(shader, 1, &shader_info->source, 0);
|
es3_functions.glShaderSource(shader, 1, &shader_info->source, 0);
|
||||||
|
Reference in New Issue
Block a user