Feat[renderer]: changes

- Better multidraw
- Fixed memory leaks in shader_wrapper
- Changed basevertex to use dumb rendering mode
This commit is contained in:
artdeell 2024-04-25 21:14:10 +03:00 committed by artdeell
parent d074ec0b41
commit bd89a868cc
8 changed files with 124 additions and 57 deletions

View File

@ -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

View File

@ -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 = &current_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);
} }*/

View 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

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View 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);
}

View File

@ -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);