From 071c026f211b872fb0fac6acaf923ff55ff64a3e Mon Sep 17 00:00:00 2001 From: dmaivel Date: Wed, 3 Jul 2024 22:08:44 -0400 Subject: [PATCH] Implement up to GL `4.4` * passthrough the vendor/renderer from the host to client * added two new environment variables for vendor/renderer overriding * vsync works in applications tested, so removed note from README * added CEIL_DIV macro for clarity * replaced long with uintptr_t for better compatibility across compilers --- README.md | 17 +- inc/sharedgl.h | 6 +- src/client/glimpl.c | 1589 +++++++++++++++++++++++++++++++++++++++- src/client/pb.c | 2 +- src/server/processor.c | 843 ++++++++++++++++++++- 5 files changed, 2433 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 93fee4b..2194db1 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ options: -o enables fps overlay on clients (shows server side fps) -n enable networking instead of shared memory -x remove shared memory file - -g [MAJOR.MINOR] report specific opengl version (default: 3.3) + -g [MAJOR.MINOR] report specific opengl version (default: 4.4) -r [WIDTHxHEIGHT] set max resolution (default: 1920x1080) -m [SIZE] max amount of megabytes program may allocate (default: 16mib) -p [PORT] if networking is enabled, specify which port to use (default: 3000) @@ -74,6 +74,8 @@ options: | GL_VERSION_OVERRIDE | Digit.Digit | | Override the OpenGL version on the client side. Otherwise, the client uses the version reported by the server. Available for both Windows and Linux clients. | | GLX_VERSION_OVERRIDE | Digit.Digit | 1.4 | Override the GLX version on the client side. Only available for Linux clients. | | GLSL_VERSION_OVERRIDE | Digit.Digit | 3.3 | Override the GLSL version on the client side. Available for both Windows and Linux clients. | +| GL_VENDOR_OVERRIDE | String | `passthrough` | Override the vendor string on the client side. Available for both Windows and Linux clients. | +| GL_RENDERER_OVERRIDE | String | `passthrough` | Override the renderer string on the client side. Available for both Windows and Linux clients. | | SGL_NET_OVER_SHARED | Ip:Port | | If networking is enabled, this environment variable must exist on the guest. Available for both Windows and Linux clients. | | SGL_RUN_WITH_LOW_PRIORITY | Boolean | true | On older CPUs, by setting the process priority to low / `IDLE_PRIORITY_CLASS`, applications will run smoother as the kernel driver is given more CPU time. This may not be needed on systems with newer CPUs. Only available for Windows clients. | @@ -246,18 +248,17 @@ This list describes the amount of functions left from each standard to implement - [x] 3.2 (~14 remaining) - [x] 3.3 (~29 remaining) - [ ] OpenGL 4 - - [ ] 4.0 (~24 remaining) (~46 total) - - [ ] 4.1 (~36 remaining) (~89 total) - - [ ] 4.2 (~4 remaining) (~12 total) - - [ ] 4.3 (~24 remaining) (~44 total) - - [ ] 4.4 (~8 remaining) (~9 total) - - [ ] 4.5 (~51 remaining) (~122 total) + - [x] 4.0 (~46 total) + - [x] 4.1 (~89 total) + - [x] 4.2 (~12 total) + - [x] 4.3 (~44 total) + - [x] 4.4 (~9 total) + - [ ] 4.5 (~42 remaining) (~122 total) - [x] 4.6 (~4 total) # Limitations / Issues - Frame glitches possible when running multiple clients - Clients may reserve too much memory according to server's allocated memory -- No Vsync - Resizing is possible, no proper implementation - New GLX FB configs may cause applications using `freeglut` or `glad` to no longer run diff --git a/inc/sharedgl.h b/inc/sharedgl.h index f7a0832..cd29edf 100644 --- a/inc/sharedgl.h +++ b/inc/sharedgl.h @@ -47,11 +47,13 @@ #define SGL_VP_DOWNLOAD_BLOCK_SIZE_IN_BYTES 3072 #define SGL_VP_DOWNLOAD_BLOCK_SIZE (SGL_VP_DOWNLOAD_BLOCK_SIZE_IN_BYTES / sizeof(int)) -#define SGL_DEFAULT_MAJOR 3 -#define SGL_DEFAULT_MINOR 3 +#define SGL_DEFAULT_MAJOR 4 +#define SGL_DEFAULT_MINOR 4 #define SGL_SHARED_MEMORY_NAME "sharedgl_shared_memory" +#define CEIL_DIV(num, den) ((num + den - 1) / den) + inline bool is_value_likely_an_offset(const void *p) { uintptr_t v = (uintptr_t)p; diff --git a/src/client/glimpl.c b/src/client/glimpl.c index ea8809c..caa3544 100644 --- a/src/client/glimpl.c +++ b/src/client/glimpl.c @@ -861,7 +861,7 @@ void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage { glimpl_submit(); - int length = (size / sizeof(int)) + (size % sizeof(int) != 0); + int length = CEIL_DIV(size, 4); if (data != NULL) { pb_push(SGL_CMD_VP_UPLOAD); @@ -1032,7 +1032,7 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) // pb_push(vap->type); // pb_push(vap->normalized); // pb_push(vap->stride); - // pb_push((int)((long)vap->ptr & 0x00000000FFFFFFFF)); + // pb_push((int)((uintptr_t)vap->ptr & 0x00000000FFFFFFFF)); // pb_push(SGL_CMD_ENABLEVERTEXATTRIBARRAY); // pb_push(vap->index); @@ -1059,7 +1059,7 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) pb_push(vap->type); pb_push(vap->normalized); pb_push(vap->stride); - pb_push(is_ptr_offset ? (int)(long)vap->ptr : 0xFFFFFFFF); // force server to use upload + pb_push(is_ptr_offset ? (int)(uintptr_t)vap->ptr : 0xFFFFFFFF); // force server to use upload pb_push(SGL_CMD_ENABLEVERTEXATTRIBARRAY); pb_push(vap->index); @@ -1253,11 +1253,25 @@ void glGetObjectParameterivARB(void *obj, GLenum pname, GLint* params) *params = GL_TRUE; } +static inline void real_glGetString(GLenum name, char *string) +{ + pb_push(SGL_CMD_GETSTRING); + pb_push(name); + + glimpl_submit(); + + uintptr_t ptr = (uintptr_t)pb_ptr(SGL_OFFSET_REGISTER_RETVAL_V); + memcpy(string, (void*)ptr, pb_read(SGL_OFFSET_REGISTER_RETVAL)); +} + const GLubyte *glGetString(GLenum name) { - static char version[16] = "X.X.0 SharedGL"; + static char version[16] = "X.X.0"; static char glsl_vr[5] = "X.X0"; + static char real_vendor[256] = ""; + static char real_renderer[256] = ""; + if (version[0] == 'X') { version[0] = '0' + (char)glimpl_major; version[2] = '0' + (char)glimpl_minor; @@ -1278,11 +1292,30 @@ const GLubyte *glGetString(GLenum name) glsl_vr[2] = '3'; } } + + char *gl_vendor_override = getenv("GL_VENDOR_OVERRIDE"); + char *gl_renderer_override = getenv("GL_RENDERER_OVERRIDE"); + + if (gl_vendor_override) { + if (strlen(gl_vendor_override) >= 256) + gl_vendor_override[256] = 0; + strcpy(real_vendor, gl_vendor_override); + } else { + real_glGetString(GL_VENDOR, real_vendor); + } + + if (gl_renderer_override) { + if (strlen(gl_renderer_override) >= 256) + gl_renderer_override[256] = 0; + strcpy(real_renderer, gl_renderer_override); + } else { + real_glGetString(GL_RENDERER, real_renderer); + } } switch (name) { - case GL_VENDOR: return (const GLubyte *)"SharedGL"; - case GL_RENDERER: return (const GLubyte *)"SharedGL Renderer"; + case GL_VENDOR: return (const GLubyte *)real_vendor; + case GL_RENDERER: return (const GLubyte *)real_renderer; case GL_VERSION: return (const GLubyte *)version; case GL_EXTENSIONS: return (const GLubyte *)glimpl_extensions_full; case GL_SHADING_LANGUAGE_VERSION: return (const GLubyte *)glsl_vr; @@ -1677,7 +1710,7 @@ void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean norm pb_push(type); pb_push(normalized); pb_push(stride); - pb_push((int)((long)pointer)); + pb_push((int)((uintptr_t)pointer)); // } } @@ -7083,7 +7116,7 @@ void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void { glimpl_submit(); - int length = (size / sizeof(int)) + (size % sizeof(int) != 0); + int length = CEIL_DIV(size, 4); pb_push(SGL_CMD_VP_UPLOAD); pb_push(length); /* could be very bad mistake */ @@ -8206,10 +8239,1548 @@ void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei strid pb_push(size); pb_push(type); pb_push(stride); - pb_push((int)((long)pointer)); + pb_push((int)((uintptr_t)pointer)); // } } +void glDrawArraysIndirect(GLenum mode, const void* indirect) +{ + /* + * to-do: instead of using this function, check if GL_DRAW_INDIRECT_BUFFER is bound + */ + if (!is_value_likely_an_offset(indirect)) { + fprintf(stderr, "glDrawArraysIndirect: expected GL_DRAW_INDIRECT_BUFFER\n"); + return; + } + + pb_push(SGL_CMD_DRAWARRAYSINDIRECT); + pb_push(mode); + pb_push((int)(uintptr_t)indirect); +} + +void glDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect) +{ + /* + * to-do: instead of using this function, check if GL_DRAW_INDIRECT_BUFFER is bound + */ + if (!is_value_likely_an_offset(indirect)) { + fprintf(stderr, "glDrawElementsIndirect: expected GL_DRAW_INDIRECT_BUFFER\n"); + return; + } + + pb_push(SGL_CMD_DRAWELEMENTSINDIRECT); + pb_push(mode); + pb_push(type); + pb_push((int)(uintptr_t)indirect); +} + +void glUniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + /* + * to-do: support doubles + * im too lazy to actually support doubles so we cast to floats + */ + int elem_count = count * 2 * 2; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glUniformMatrix2fv(location, count, transpose, valuef); +} + +void glUniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 3 * 3; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glUniformMatrix3fv(location, count, transpose, valuef); +} + +void glUniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 4 * 4; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glUniformMatrix4fv(location, count, transpose, valuef); +} + +void glUniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 2 * 3; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glUniformMatrix2x3fv(location, count, transpose, valuef); +} + +void glUniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 2 * 4; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glUniformMatrix2x4fv(location, count, transpose, valuef); +} + +void glUniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 3 * 2; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glUniformMatrix3x2fv(location, count, transpose, valuef); +} + +void glUniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 3 * 4; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glUniformMatrix3x4fv(location, count, transpose, valuef); +} + +void glUniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 4 * 2; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glUniformMatrix4x2fv(location, count, transpose, valuef); +} + +void glUniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 4 * 3; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glUniformMatrix4x3fv(location, count, transpose, valuef); +} + +void glGetUniformdv(GLuint program, GLint location, GLdouble* params) +{ + // very wrong + glGetUniformfv(program, location, params); +} + +GLint glGetSubroutineUniformLocation(GLuint program, GLenum shadertype, const GLchar* name) +{ + pb_push(SGL_CMD_GETSUBROUTINEUNIFORMLOCATION); + pb_push(program); + pb_push(shadertype); + push_string(name); + + glimpl_submit(); + return pb_read(SGL_OFFSET_REGISTER_RETVAL); +} + +GLuint glGetSubroutineIndex(GLuint program, GLenum shadertype, const GLchar* name) +{ + pb_push(SGL_CMD_GETSUBROUTINEINDEX); + pb_push(program); + pb_push(shadertype); + push_string(name); + + glimpl_submit(); + return pb_read(SGL_OFFSET_REGISTER_RETVAL); +} + +void glGetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint* values) +{ + pb_push(SGL_CMD_GETACTIVESUBROUTINEUNIFORMIV); + pb_push(program); + pb_push(shadertype); + pb_push(index); + pb_push(pname); + + glimpl_submit(); + switch (pname) { + case GL_COMPATIBLE_SUBROUTINES: { + int num = pb_read(SGL_OFFSET_REGISTER_RETVAL); + int *vals = values; + for (int i = 0; i < pb_read(SGL_OFFSET_REGISTER_RETVAL); i++) + *vals++ = pb_read(SGL_OFFSET_REGISTER_RETVAL_V + (i * 4)); + break; + } + default: + *values = pb_read(SGL_OFFSET_REGISTER_RETVAL); + break; + } +} + +void glGetActiveSubroutineUniformName(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar* name) +{ + pb_push(SGL_CMD_GETACTIVESUBROUTINEUNIFORMNAME); + pb_push(program); + pb_push(shadertype); + pb_push(index); + pb_push(bufsize); + + glimpl_submit(); + + uintptr_t ptr = (uintptr_t)pb_ptr(SGL_OFFSET_REGISTER_RETVAL_V); + GLsizei length_notptr; + + memcpy(&length_notptr, (void*)(ptr + 0), sizeof(*length)); + if (length != NULL) + *length = length_notptr; + + memcpy(name, (void*)(ptr + sizeof(*length)), length_notptr); +} + +void glGetActiveSubroutineName(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei* length, GLchar* name) +{ + pb_push(SGL_CMD_GETACTIVESUBROUTINENAME); + pb_push(program); + pb_push(shadertype); + pb_push(index); + pb_push(bufsize); + + glimpl_submit(); + + uintptr_t ptr = (uintptr_t)pb_ptr(SGL_OFFSET_REGISTER_RETVAL_V); + GLsizei length_notptr; + + memcpy(&length_notptr, (void*)(ptr + 0), sizeof(*length)); + if (length != NULL) + *length = length_notptr; + + memcpy(name, (void*)(ptr + sizeof(*length)), length_notptr); +} + +void glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint* indices) +{ + pb_push(SGL_CMD_UNIFORMSUBROUTINESUIV); + pb_push(shadertype); + pb_push(count); + + for (int i = 0; i < count; i++) + pb_push(indices[i]); +} + +void glGetUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint* params) +{ + pb_push(SGL_CMD_GETUNIFORMSUBROUTINEUIV); + pb_push(shadertype); + pb_push(location); + + *params = pb_read(SGL_OFFSET_REGISTER_RETVAL_V); +} + +void glGetProgramStageiv(GLuint program, GLenum shadertype, GLenum pname, GLint* values) +{ + pb_push(SGL_CMD_GETPROGRAMSTAGEIV); + pb_push(program); + pb_push(shadertype); + pb_push(pname); + + glimpl_submit(); + *values = pb_read(SGL_OFFSET_REGISTER_RETVAL_V); +} + +void glPatchParameterfv(GLenum pname, const GLfloat* values) +{ + int count = pname == GL_PATCH_DEFAULT_OUTER_LEVEL ? 4 : 2; + + pb_push(SGL_CMD_PATCHPARAMETERFV); + pb_push(pname); + pb_push(count); + + for (int i = 0; i < count; i++) + pb_pushf(values[i]); +} + +void glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) +{ + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_DELETETRANSFORMFEEDBACKS); + // pb_push(1); + + pb_push(ids[i]); + } +} + +void glGenTransformFeedbacks(GLsizei n, GLuint* ids) +{ + GLuint *p = ids; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_GENTRANSFORMFEEDBACKS); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glGetQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint* params) +{ + pb_push(SGL_CMD_GETQUERYINDEXEDIV); + pb_push(target); + pb_push(index); + pb_push(pname); + + glimpl_submit(); + *params = pb_read(SGL_OFFSET_REGISTER_RETVAL_V); +} + +void glShaderBinary(GLsizei count, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) +{ + pb_push(SGL_CMD_SHADERBINARY); + pb_push(count); + pb_push(binaryformat); + pb_push(length); + for (int i = 0; i < count; i++) + pb_push(shaders[i]); + pb_memcpy((void*)binary, length); +} + +void glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) +{ + pb_push(SGL_CMD_GETSHADERPRECISIONFORMAT); + pb_push(shadertype); + pb_push(precisiontype); + pb_push(range[0]); + pb_push(range[1]); + + glimpl_submit(); + *precision = pb_read(SGL_OFFSET_REGISTER_RETVAL); +} + +void glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary) +{ + // pb_push(SGL_CMD_GETPROGRAMBINARY); + // pb_push(program); + // pb_push(bufSize); + + fprintf(stderr, "glGetProgramBinary: stub\n"); + +} + +void glProgramBinary(GLuint program, GLenum binaryFormat, const void* binary, GLsizei length) +{ + pb_push(SGL_CMD_SHADERBINARY); + pb_push(program); + pb_push(binaryFormat); + pb_push(length); + pb_memcpy((void*)binary, length); +} + +GLuint glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar* const*strings) +{ + pb_push(SGL_CMD_CREATESHADERPROGRAMV); + pb_push(type); + pb_push(count); + + glimpl_submit(); + return pb_read(SGL_OFFSET_REGISTER_RETVAL); +} + + +void glDeleteProgramPipelines(GLsizei n, const GLuint* pipelines) +{ + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_DELETEPROGRAMPIPELINES); + // pb_push(1); + + pb_push(pipelines[i]); + } +} + +void glGenProgramPipelines(GLsizei n, GLuint* pipelines) +{ + GLuint *p = pipelines; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_GENPROGRAMPIPELINES); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint* params) +{ + pb_push(SGL_CMD_GETPROGRAMPIPELINEIV); + pb_push(pipeline); + pb_push(pname); + + glimpl_submit(); + *params = pb_read(SGL_OFFSET_REGISTER_RETVAL); +} + +void glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 2 * 2); + for (int i = 0; i < count * 2 * 2; i++) + pb_pushf(value[i]); + + pb_push(SGL_CMD_PROGRAMUNIFORMMATRIX2FV); + pb_push(program); + pb_push(location); + pb_push(count); + pb_push(transpose); +} + +void glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 3 * 3); + for (int i = 0; i < count * 3 * 3; i++) + pb_pushf(value[i]); + + pb_push(SGL_CMD_PROGRAMUNIFORMMATRIX3FV); + pb_push(program); + pb_push(location); + pb_push(count); + pb_push(transpose); +} + +void glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 4 * 4); + for (int i = 0; i < count * 4 * 4; i++) + pb_pushf(value[i]); + + pb_push(SGL_CMD_PROGRAMUNIFORMMATRIX4FV); + pb_push(program); + pb_push(location); + pb_push(count); + pb_push(transpose); +} + +void glProgramUniformMatrix2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 2 * 2; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glProgramUniformMatrix2fv(program, location, count, transpose, valuef); +} + +void glProgramUniformMatrix3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 3 * 3; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glProgramUniformMatrix3fv(program, location, count, transpose, valuef); +} + +void glProgramUniformMatrix4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 4 * 4; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glProgramUniformMatrix4fv(program, location, count, transpose, valuef); +} + +void glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 2 * 3); + for (int i = 0; i < count * 2 * 3; i++) + pb_pushf(value[i]); + + pb_push(SGL_CMD_PROGRAMUNIFORMMATRIX2X3FV); + pb_push(program); + pb_push(location); + pb_push(count); + pb_push(transpose); +} + +void glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 3 * 2); + for (int i = 0; i < count * 3 * 2; i++) + pb_pushf(value[i]); + + pb_push(SGL_CMD_PROGRAMUNIFORMMATRIX3X2FV); + pb_push(program); + pb_push(location); + pb_push(count); + pb_push(transpose); +} + +void glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 2 * 4); + for (int i = 0; i < count * 2 * 4; i++) + pb_pushf(value[i]); + + pb_push(SGL_CMD_PROGRAMUNIFORMMATRIX2X4FV); + pb_push(program); + pb_push(location); + pb_push(count); + pb_push(transpose); +} + +void glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 4 * 2); + for (int i = 0; i < count * 4 * 2; i++) + pb_pushf(value[i]); + + pb_push(SGL_CMD_PROGRAMUNIFORMMATRIX4X2FV); + pb_push(program); + pb_push(location); + pb_push(count); + pb_push(transpose); +} + +void glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 3 * 4); + for (int i = 0; i < count * 3 * 4; i++) + pb_pushf(value[i]); + + pb_push(SGL_CMD_PROGRAMUNIFORMMATRIX3X4FV); + pb_push(program); + pb_push(location); + pb_push(count); + pb_push(transpose); +} + +void glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 4 * 3); + for (int i = 0; i < count * 4 * 3; i++) + pb_pushf(value[i]); + + pb_push(SGL_CMD_PROGRAMUNIFORMMATRIX4X3FV); + pb_push(program); + pb_push(location); + pb_push(count); + pb_push(transpose); +} + +void glProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 2 * 3; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glProgramUniformMatrix2x3fv(program, location, count, transpose, valuef); +} + +void glProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 3 * 2; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glProgramUniformMatrix3x2fv(program, location, count, transpose, valuef); +} + +void glProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 2 * 4; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glProgramUniformMatrix2x4fv(program, location, count, transpose, valuef); +} + +void glProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 4 * 2; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glProgramUniformMatrix4x2fv(program, location, count, transpose, valuef); +} + +void glProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 3 * 4; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glProgramUniformMatrix3x4fv(program, location, count, transpose, valuef); +} + +void glProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) +{ + int elem_count = count * 4 * 3; + GLfloat valuef[elem_count]; + for (int i = 0; i < elem_count; i++) + valuef[i] = value[i]; + glProgramUniformMatrix4x3fv(program, location, count, transpose, valuef); +} + +void glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) +{ + pb_push(SGL_CMD_GETPROGRAMPIPELINEINFOLOG); + pb_push(pipeline); + pb_push(bufSize); + + glimpl_submit(); + + uintptr_t ptr = (uintptr_t)pb_ptr(SGL_OFFSET_REGISTER_RETVAL_V); + GLsizei length_notptr; + + memcpy(&length_notptr, (void*)(ptr + 0), sizeof(*length)); + if (length != NULL) + *length = length_notptr; + + memcpy(infoLog, (void*)(ptr + sizeof(*length)), length_notptr); +} + +void glVertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) +{ + bool client_managed = !is_value_likely_an_offset(pointer); + + glimpl_vaps[index] = (struct gl_vertex_attrib_pointer){ + .index = index, + .size = size, + .type = type, + .normalized = GL_FALSE, + .stride = stride, + .ptr = (void*)pointer, + .enabled = false, + .client_managed = client_managed + }; + + // if (!client_managed) { + pb_push(SGL_CMD_VERTEXATTRIBLPOINTER); + pb_push(index); + pb_push(size); + pb_push(type); + pb_push(stride); + pb_push((int)((uintptr_t)pointer)); + // } +} + +void glGetVertexAttribLdv(GLuint index, GLenum pname, GLdouble* params) +{ + // wrong + glGetVertexAttribdv(index, pname, params); +} + +void glViewportArrayv(GLuint first, GLsizei count, const GLfloat* v) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 4); + for (int i = 0; i < count * 4; i++) + pb_pushf(v[i]); + + pb_push(SGL_CMD_VIEWPORTARRAYV); + pb_push(first); + pb_push(count); +} + +void glViewportIndexedfv(GLuint index, const GLfloat* v) +{ + glViewportIndexedf(index, v[0], v[1], v[2], v[3]); +} + +void glScissorArrayv(GLuint first, GLsizei count, const GLint* v) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 4); + for (int i = 0; i < count * 4; i++) + pb_pushf(v[i]); + + pb_push(SGL_CMD_SCISSORARRAYV); + pb_push(first); + pb_push(count); +} + +void glScissorIndexedv(GLuint index, const GLint* v) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(4); + for (int i = 0; i < 4; i++) + pb_pushf(v[i]); + + pb_push(SGL_CMD_SCISSORINDEXEDV); + pb_push(index); +} + +void glDepthRangeArrayv(GLuint first, GLsizei count, const GLdouble* v) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count * 2); + for (int i = 0; i < count * 2; i++) + pb_pushf(v[i]); + + pb_push(SGL_CMD_DEPTHRANGEARRAYV); + pb_push(first); + pb_push(count); +} + +void glGetFloati_v(GLenum target, GLuint index, GLfloat* data) +{ + pb_push(SGL_CMD_GETINTEGERI_V); + pb_push(target); + pb_push(index); + glimpl_submit(); + GL_GET_MEMCPY_RETVAL_EX(target, data, GLfloat); +} + +void glGetDoublei_v(GLenum target, GLuint index, GLdouble* data) +{ + pb_push(SGL_CMD_GETDOUBLEI_V); + pb_push(target); + pb_push(index); + glimpl_submit(); + GL_GET_MEMCPY_RETVAL_EX(target, data, GLfloat); +} + +// 4.2 + +void glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLuint baseinstance) +{ + /* + * to-do: check if GL_ELEMENT_ARRAY_BUFFER is bound + */ + if (!is_value_likely_an_offset(indices)) { + fprintf(stderr, "glDrawElementsInstancedBaseInstance: expected GL_ELEMENT_ARRAY_BUFFER\n"); + return; + } + + pb_push(SGL_CMD_DRAWELEMENTSINSTANCEDBASEINSTANCE); + pb_push(mode); + pb_push(count); + pb_push(type); + pb_push((uintptr_t)indices); + pb_push(instancecount); + pb_push(baseinstance); +} + +void glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance) +{ + if (!is_value_likely_an_offset(indices)) { + fprintf(stderr, "glDrawElementsInstancedBaseVertexBaseInstance: expected GL_ELEMENT_ARRAY_BUFFER\n"); + return; + } + + pb_push(SGL_CMD_DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE); + pb_push(mode); + pb_push(count); + pb_push(type); + pb_push((uintptr_t)indices); + pb_push(instancecount); + pb_push(basevertex); + pb_push(baseinstance); +} + +void glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) +{ + fprintf(stderr, "glGetInternalformativ: stub\n"); +} + +void glGetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, GLenum pname, GLint* params) +{ + pb_push(SGL_CMD_GETACTIVEATOMICCOUNTERBUFFERIV); + pb_push(program); + pb_push(bufferIndex); + pb_push(pname); + + glimpl_submit(); + switch (pname) { + case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES: { + int num = pb_read(SGL_OFFSET_REGISTER_RETVAL); + int *vals = params; + for (int i = 0; i < pb_read(SGL_OFFSET_REGISTER_RETVAL); i++) + *vals++ = pb_read(SGL_OFFSET_REGISTER_RETVAL_V + (i * 4)); + break; + } + default: + *params = pb_read(SGL_OFFSET_REGISTER_RETVAL); + break; + } +} + +// 4.3 + +void glClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void* data) +{ + pb_push(SGL_CMD_CLEARBUFFERDATA); + pb_push(target); + pb_push(internalformat); + pb_push(format); + pb_push(type); + pb_push(*(unsigned int*)data); +} + +void glClearBufferSubData(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void* data) +{ + pb_push(SGL_CMD_CLEARBUFFERSUBDATA); + pb_push(target); + pb_push(internalformat); + pb_push(offset); + pb_push(size); + pb_push(format); + pb_push(type); + pb_push(*(unsigned int*)data); +} + +void glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint* params) +{ + pb_push(SGL_CMD_GETFRAMEBUFFERPARAMETERIV); + pb_push(target); + pb_push(pname); + + glimpl_submit(); + *params = pb_read(SGL_OFFSET_REGISTER_RETVAL); +} + +void glGetInternalformati64v(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64* params) +{ + fprintf(stderr, "glGetInternalformati64v: stub\n"); +} + +void glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(numAttachments); + for (int i = 0; i < numAttachments; i++) + pb_pushf(attachments[i]); + + pb_push(SGL_CMD_INVALIDATEFRAMEBUFFER); + pb_push(target); + pb_push(numAttachments); +} + +void glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(numAttachments); + for (int i = 0; i < numAttachments; i++) + pb_pushf(attachments[i]); + + pb_push(SGL_CMD_INVALIDATESUBFRAMEBUFFER); + pb_push(target); + pb_push(numAttachments); + pb_push(x); + pb_push(y); + pb_push(width); + pb_push(height); +} + +void glMultiDrawArraysIndirect(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) +{ + for (int i = 0; i < drawcount; i++) + glDrawArraysIndirect(mode, (char *)indirect + i * stride); +} + +void glMultiDrawElementsIndirect(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride) +{ + for (int i = 0; i < drawcount; i++) + glDrawElementsIndirect(mode, type, (char *)indirect + i * stride); +} + +void glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint* params) +{ + pb_push(SGL_CMD_GETPROGRAMINTERFACEIV); + pb_push(program); + pb_push(programInterface); + pb_push(pname); + + glimpl_submit(); + *params = pb_read(SGL_OFFSET_REGISTER_RETVAL); +} + +GLuint glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar* name) +{ + pb_push(SGL_CMD_GETPROGRAMRESOURCEINDEX); + pb_push(program); + pb_push(programInterface); + push_string(name); + + glimpl_submit(); + return pb_read(SGL_OFFSET_REGISTER_RETVAL); +} + +void glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) +{ + pb_push(SGL_CMD_GETPROGRAMRESOURCENAME); + pb_push(program); + pb_push(programInterface); + pb_push(index); + pb_push(bufSize); + + glimpl_submit(); + + uintptr_t ptr = (uintptr_t)pb_ptr(SGL_OFFSET_REGISTER_RETVAL_V); + GLsizei length_notptr; + + memcpy(&length_notptr, (void*)(ptr + 0), sizeof(*length)); + if (length != NULL) + *length = length_notptr; + + memcpy(name, (void*)(ptr + sizeof(*length)), length_notptr); +} + +void glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(propCount); + for (int i = 0; i < propCount; i++) + pb_push(props[i]); + + pb_push(SGL_CMD_GETPROGRAMRESOURCEIV); + pb_push(program); + pb_push(programInterface); + pb_push(index); + pb_push(propCount); + pb_push(bufSize); + + glimpl_submit(); + + uintptr_t ptr = (uintptr_t)pb_ptr(SGL_OFFSET_REGISTER_RETVAL_V); + GLsizei length_notptr; + + memcpy(&length_notptr, (void*)(ptr + 0), sizeof(*length)); + if (length != NULL) + *length = length_notptr; + + memcpy(params, (void*)(ptr + sizeof(*length)), length_notptr * 4); +} + +GLint glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar* name) +{ + pb_push(SGL_CMD_GETPROGRAMRESOURCELOCATION); + pb_push(program); + pb_push(programInterface); + push_string(name); + + glimpl_submit(); + return pb_read(SGL_OFFSET_REGISTER_RETVAL); +} + +GLint glGetProgramResourceLocationIndex(GLuint program, GLenum programInterface, const GLchar* name) +{ + pb_push(SGL_CMD_GETPROGRAMRESOURCELOCATIONINDEX); + pb_push(program); + pb_push(programInterface); + push_string(name); + + glimpl_submit(); + return pb_read(SGL_OFFSET_REGISTER_RETVAL); +} + +void glDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled) +{ + +} + +void glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf) +{ + +} + +void glDebugMessageCallback(GLDEBUGPROC callback, const void* userParam) +{ + +} + +GLuint glGetDebugMessageLog(GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) +{ + +} + +void glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message) +{ + +} + +void glObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar* label) +{ + +} + +void glGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) +{ + +} + +void glObjectPtrLabel(const void* ptr, GLsizei length, const GLchar* label) +{ + +} + +void glGetObjectPtrLabel(const void* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) +{ + +} + +// 4.4 + +void glBufferStorage(GLenum target, GLsizeiptr size, const void* data, GLbitfield flags) +{ + glimpl_submit(); + + int length = CEIL_DIV(size, 4); + + if (data != NULL) { + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(length); /* could be very bad mistake */ + unsigned int *idata = (unsigned int*)data; + for (int i = 0; i < length; i++) + pb_push(idata[i]); + } + + pb_push(SGL_CMD_BUFFERSTORAGE); + pb_push(target); + pb_push(size); + pb_push(data != NULL); + pb_push(flags); + + glimpl_submit(); +} + +void glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, const void* data) +{ + pb_push(SGL_CMD_CLEARTEXIMAGE); + pb_push(texture); + pb_push(level); + pb_push(format); + pb_push(type); + pb_push(*(unsigned int*)data); +} + +void glClearTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* data) +{ + pb_push(SGL_CMD_CLEARTEXSUBIMAGE); + pb_push(texture); + pb_push(level); + pb_push(xoffset); + pb_push(yoffset); + pb_push(zoffset); + pb_push(width); + pb_push(height); + pb_push(depth); + pb_push(format); + pb_push(type); + pb_push(*(unsigned int*)data); +} + +void glBindBuffersRange(GLenum target, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr* offsets, const GLsizeiptr* sizes) +{ + pb_push(SGL_CMD_BINDBUFFERSRANGE); + pb_push(target); + pb_push(first); + pb_push(count); + for (int i = 0; i < count; i++) { + pb_push(buffers[i]); + pb_push(offsets[i]); + pb_push(sizes[i]); + } +} + +void glBindTextures(GLuint first, GLsizei count, const GLuint* textures) +{ + // to-do: have compatability option? + // for (GLuint i = 0; i < count; i++) { + // glActiveTexture(GL_TEXTURE0 + first + i); + // glBindTexture(GL_TEXTURE_2D, textures[i]); + // } + + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count); + for (int i = 0; i < count; i++) + pb_push(textures[i]); + + pb_push(SGL_CMD_BINDTEXTURES); + pb_push(first); + pb_push(count); +} + +void glBindSamplers(GLuint first, GLsizei count, const GLuint* samplers) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count); + for (int i = 0; i < count; i++) + pb_push(samplers[i]); + + pb_push(SGL_CMD_BINDSAMPLERS); + pb_push(first); + pb_push(count); +} + +void glBindImageTextures(GLuint first, GLsizei count, const GLuint* textures) +{ + pb_push(SGL_CMD_VP_UPLOAD); + pb_push(count); + for (int i = 0; i < count; i++) + pb_push(textures[i]); + + pb_push(SGL_CMD_BINDIMAGETEXTURES); + pb_push(first); + pb_push(count); +} + +void glBindVertexBuffers(GLuint first, GLsizei count, const GLuint* buffers, const GLintptr* offsets, const GLsizei* strides) +{ + pb_push(SGL_CMD_BINDVERTEXBUFFERS); + pb_push(first); + pb_push(count); + for (int i = 0; i < count; i++) { + pb_push(buffers[i]); + pb_push(offsets[i]); + pb_push(strides[i]); + } +} + +// 4.5 + +void glCreateTransformFeedbacks(GLsizei n, GLuint* ids) +{ + GLuint *p = ids; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_CREATETRANSFORMFEEDBACKS); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glGetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint* param) +{ + +} + +void glGetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint* param) +{ + +} + +void glGetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64* param) +{ + +} + +void glCreateBuffers(GLsizei n, GLuint* buffers) +{ + GLuint *p = buffers; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_CREATEBUFFERS); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void* data, GLbitfield flags) +{ + +} + +void glNamedBufferData(GLuint buffer, GLsizeiptr size, const void* data, GLenum usage) +{ + +} + +void glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data) +{ + +} + +void glClearNamedBufferData(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void* data) +{ + +} + +void glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void* data) +{ + +} + +void* glMapNamedBuffer(GLuint buffer, GLenum access) +{ + +} + +void* glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access) +{ + +} + +void glGetNamedBufferParameteriv(GLuint buffer, GLenum pname, GLint* params) +{ + +} + +void glGetNamedBufferParameteri64v(GLuint buffer, GLenum pname, GLint64* params) +{ + +} + +void glGetNamedBufferPointerv(GLuint buffer, GLenum pname, void* *params) +{ + +} + +void glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void* data) +{ + +} + +void glCreateFramebuffers(GLsizei n, GLuint* framebuffers) +{ + GLuint *p = framebuffers; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_CREATEFRAMEBUFFERS); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glNamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n, const GLenum* bufs) +{ + +} + +void glInvalidateNamedFramebufferData(GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments) +{ + +} + +void glInvalidateNamedFramebufferSubData(GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) +{ + +} + +void glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value) +{ + +} + +void glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value) +{ + +} + +void glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value) +{ + +} + +void glGetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname, GLint* param) +{ + +} + +void glGetNamedFramebufferAttachmentParameteriv(GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params) +{ + +} + +void glCreateRenderbuffers(GLsizei n, GLuint* renderbuffers) +{ + GLuint *p = renderbuffers; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_CREATERENDERBUFFERS); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glGetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, GLint* params) +{ + +} + +void glCreateTextures(GLenum target, GLsizei n, GLuint* textures) +{ + GLuint *p = textures; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_CREATETEXTURES); + pb_push(target); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels) +{ + +} + +void glTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) +{ + +} + +void glCompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data) +{ + +} + +void glCompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) +{ + +} + +void glCompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) +{ + +} + +void glTextureParameterfv(GLuint texture, GLenum pname, const GLfloat* param) +{ + +} + +void glTextureParameterIiv(GLuint texture, GLenum pname, const GLint* params) +{ + +} + +void glTextureParameterIuiv(GLuint texture, GLenum pname, const GLuint* params) +{ + +} + +void glTextureParameteriv(GLuint texture, GLenum pname, const GLint* param) +{ + +} + +void glGetTextureImage(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* pixels) +{ + +} + +void glGetCompressedTextureImage(GLuint texture, GLint level, GLsizei bufSize, void* pixels) +{ + +} + +void glGetTextureLevelParameterfv(GLuint texture, GLint level, GLenum pname, GLfloat* params) +{ + +} + +void glGetTextureLevelParameteriv(GLuint texture, GLint level, GLenum pname, GLint* params) +{ + +} + +void glGetTextureParameterfv(GLuint texture, GLenum pname, GLfloat* params) +{ + +} + +void glGetTextureParameterIiv(GLuint texture, GLenum pname, GLint* params) +{ + +} + +void glGetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint* params) +{ + +} + +void glGetTextureParameteriv(GLuint texture, GLenum pname, GLint* params) +{ + +} + +void glCreateVertexArrays(GLsizei n, GLuint* arrays) +{ + GLuint *p = arrays; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_CREATEVERTEXARRAYS); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glVertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr* offsets, const GLsizei* strides) +{ + +} + +void glGetVertexArrayiv(GLuint vaobj, GLenum pname, GLint* param) +{ + +} + +void glGetVertexArrayIndexediv(GLuint vaobj, GLuint index, GLenum pname, GLint* param) +{ + +} + +void glGetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, GLenum pname, GLint64* param) +{ + +} + +void glCreateSamplers(GLsizei n, GLuint* samplers) +{ + GLuint *p = samplers; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_CREATESAMPLERS); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glCreateProgramPipelines(GLsizei n, GLuint* pipelines) +{ + GLuint *p = pipelines; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_CREATEPROGRAMPIPELINES); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glCreateQueries(GLenum target, GLsizei n, GLuint* ids) +{ + GLuint *p = ids; + + for (int i = 0; i < n; i++) { + pb_push(SGL_CMD_CREATEQUERIES); + pb_push(target); + // pb_push(1); + + glimpl_submit(); + *p++ = pb_read(SGL_OFFSET_REGISTER_RETVAL); + } +} + +void glGetTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void* pixels) +{ + +} + +void glGetCompressedTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void* pixels) +{ + +} + +void glGetnCompressedTexImage(GLenum target, GLint lod, GLsizei bufSize, void* pixels) +{ + +} + +void glGetnTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void* pixels) +{ + +} + +void glGetnUniformdv(GLuint program, GLint location, GLsizei bufSize, GLdouble* params) +{ + +} + +void glGetnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) +{ + +} + +void glGetnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint* params) +{ + +} + +void glGetnUniformuiv(GLuint program, GLint location, GLsizei bufSize, GLuint* params) +{ + +} + +void glReadnPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void* data) +{ + +} + +void glGetnMapdv(GLenum target, GLenum query, GLsizei bufSize, GLdouble* v) +{ + +} + +void glGetnMapfv(GLenum target, GLenum query, GLsizei bufSize, GLfloat* v) +{ + +} + +void glGetnMapiv(GLenum target, GLenum query, GLsizei bufSize, GLint* v) +{ + +} + +void glGetnPixelMapfv(GLenum map, GLsizei bufSize, GLfloat* values) +{ + +} + +void glGetnPixelMapuiv(GLenum map, GLsizei bufSize, GLuint* values) +{ + +} + +void glGetnPixelMapusv(GLenum map, GLsizei bufSize, GLushort* values) +{ + +} + +void glGetnPolygonStipple(GLsizei bufSize, GLubyte* pattern) +{ + +} + +void glGetnColorTable(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* table) +{ + +} + +void glGetnConvolutionFilter(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void* image) +{ + +} + +void glGetnSeparableFilter(GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void* row, GLsizei columnBufSize, void* column, void* span) +{ + +} + +void glGetnHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values) +{ + +} + +void glGetnMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void* values) +{ + +} + #ifdef _WIN32 static const GLCLTPROCTABLE cpt = diff --git a/src/client/pb.c b/src/client/pb.c index ce8d056..95c26e9 100644 --- a/src/client/pb.c +++ b/src/client/pb.c @@ -192,7 +192,7 @@ void pb_memcpy(void *src, size_t length) { // length = length - (length % 4); memcpy(in_cur, src, length); - in_cur += (length / 4); + in_cur += CEIL_DIV(length, 4); } void *pb_ptr(size_t offs) diff --git a/src/server/processor.c b/src/server/processor.c index 9a0ad64..875b34e 100644 --- a/src/server/processor.c +++ b/src/server/processor.c @@ -35,7 +35,7 @@ static struct sgl_connection *connections = NULL; static bool match_connection(void *elem, void *data) { struct sgl_connection *con = elem; - int id = (long)data; + int id = (uintptr_t)data; if (con->id == id) sgl_context_destroy(con->ctx); @@ -85,7 +85,7 @@ static void connection_rem(int id, struct net_context *net_ctx) { if (net_ctx != NULL) net_close(net_ctx, get_fd_from_id(id)); - dynarr_free_element((void**)&connections, 0, match_connection, (void*)((long)id)); + dynarr_free_element((void**)&connections, 0, match_connection, (void*)((uintptr_t)id)); } static bool wait_for_submit(void *p) @@ -896,7 +896,7 @@ void sgl_cmd_processor_start(struct sgl_cmd_processor_args args) normalized = *pb++, stride = *pb++, ptr = *pb++; - glVertexAttribPointer(index, size, type, normalized, stride, !is_value_likely_an_offset((void*)(long)ptr) ? uploaded : (void*)(long)ptr); + glVertexAttribPointer(index, size, type, normalized, stride, !is_value_likely_an_offset((void*)(uintptr_t)ptr) ? uploaded : (void*)(uintptr_t)ptr); break; } case SGL_CMD_VIEWPORT: { @@ -4782,7 +4782,7 @@ void sgl_cmd_processor_start(struct sgl_cmd_processor_args args) type = *pb++, stride = *pb++, ptr = *pb++; - glVertexAttribIPointer(index, size, type, stride, !is_value_likely_an_offset((void*)(long)ptr) ? uploaded : (void*)(long)ptr); + glVertexAttribIPointer(index, size, type, stride, !is_value_likely_an_offset((void*)(uintptr_t)ptr) ? uploaded : (void*)(uintptr_t)ptr); break; } case SGL_CMD_MAPBUFFERRANGE: { @@ -4823,6 +4823,841 @@ void sgl_cmd_processor_start(struct sgl_cmd_processor_args args) glDrawBuffers(n, bufs); break; } + case SGL_CMD_DRAWARRAYSINDIRECT: { + int mode = *pb++, + offset = *pb++; + glDrawArraysIndirect(mode, (void*)(uintptr_t)offset); + break; + } + case SGL_CMD_DRAWELEMENTSINDIRECT: { + int mode = *pb++, + type = *pb++, + offset = *pb++; + glDrawElementsIndirect(mode, type, (void*)(uintptr_t)offset); + break; + } + case SGL_CMD_GETSUBROUTINEUNIFORMLOCATION: { + int program = *pb++; + int shadertype = *pb++; + char *name = (char*)pb; + ADVANCE_PAST_STRING(); + + *(int*)(p + SGL_OFFSET_REGISTER_RETVAL) = glGetSubroutineUniformLocation(program, shadertype, name); + break; + } + case SGL_CMD_GETSUBROUTINEINDEX: { + int program = *pb++; + int shadertype = *pb++; + char *name = (char*)pb; + ADVANCE_PAST_STRING(); + + *(int*)(p + SGL_OFFSET_REGISTER_RETVAL) = glGetSubroutineIndex(program, shadertype, name); + break; + } + case SGL_CMD_GETACTIVESUBROUTINEUNIFORMIV: { + int program = *pb++; + int shadertype = *pb++; + int index = *pb++; + int pname = *pb++; + + if (pname == GL_COMPATIBLE_SUBROUTINES) { + glGetActiveSubroutineUniformiv(program, shadertype, index, GL_NUM_COMPATIBLE_SUBROUTINES, (int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + glGetActiveSubroutineUniformiv(program, shadertype, index, GL_COMPATIBLE_SUBROUTINES, (int*)(p + SGL_OFFSET_REGISTER_RETVAL_V)); + } else { + glGetActiveSubroutineUniformiv(program, shadertype, index, pname, (int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + } + + break; + } + case SGL_CMD_GETACTIVESUBROUTINEUNIFORMNAME: { + int program = *pb++; + int shadertype = *pb++; + int index = *pb++; + int bufsize = *pb++; + + glGetActiveSubroutineUniformName(program, shadertype, index, bufsize, + p + SGL_OFFSET_REGISTER_RETVAL_V, + p + SGL_OFFSET_REGISTER_RETVAL_V + sizeof(GLsizei) + ); + + break; + } + case SGL_CMD_GETACTIVESUBROUTINENAME: { + int program = *pb++; + int shadertype = *pb++; + int index = *pb++; + int bufsize = *pb++; + + glGetActiveSubroutineName(program, shadertype, index, bufsize, + p + SGL_OFFSET_REGISTER_RETVAL_V, + p + SGL_OFFSET_REGISTER_RETVAL_V + sizeof(GLsizei) + ); + + break; + } + case SGL_CMD_UNIFORMSUBROUTINESUIV: { + int shadertype = *pb++; + int count = *pb++; + unsigned int indices[count]; + + for (int i = 0; i < count; i++) + indices[i] = *pb++; + + glUniformSubroutinesuiv(shadertype, count, indices); + break; + } + case SGL_CMD_GETUNIFORMSUBROUTINEUIV: { + int shadertype = *pb++; + int location = *pb++; + + glGetUniformSubroutineuiv(shadertype, location, p + SGL_OFFSET_REGISTER_RETVAL_V); + break; + } + case SGL_CMD_GETPROGRAMSTAGEIV: { + int program = *pb++; + int shadertype = *pb++; + int pname = *pb++; + + glGetProgramStageiv(program, shadertype, pname, p + SGL_OFFSET_REGISTER_RETVAL_V); + break; + } + case SGL_CMD_PATCHPARAMETERFV: { + int pname = *pb++; + int count = *pb++; + float values[count]; + for (int i = 0; i < count; i++) + values[i] = *((float*)pb++); + glPatchParameterfv(pname, values); + break; + } + case SGL_CMD_DELETETRANSFORMFEEDBACKS: { + unsigned int buffer = *pb++; + glDeleteTransformFeedbacks(1, &buffer); + break; + } + case SGL_CMD_GENTRANSFORMFEEDBACKS: { + glGenTransformFeedbacks(1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_GETQUERYINDEXEDIV: { + int target = *pb++; + int index = *pb++; + int pname = *pb++; + glGetQueryIndexediv(target, index, pname, p + SGL_OFFSET_REGISTER_RETVAL_V); + break; + } + case SGL_CMD_SHADERBINARY: { + int count = *pb++; + int binaryformat = *pb++; + int length = *pb++; + + unsigned int shaders[count]; + for (int i = 0; i < count; i++) + shaders[i] = *pb++; + + void *binary = pb; + pb += CEIL_DIV(length, 4); + + glShaderBinary(count, shaders, binaryformat, binary, length); + break; + } + case SGL_CMD_GETSHADERPRECISIONFORMAT: { + int shadertype = *pb++; + int precisiontype = *pb++; + int range[2]; + range[0] = *pb++; + range[1] = *pb++; + glGetShaderPrecisionFormat(shadertype, precisiontype, range, p + SGL_OFFSET_REGISTER_RETVAL_V); + break; + } + case SGL_CMD_GETPROGRAMBINARY: { + int program = *pb++; + int bufSize = *pb++; + + + break; + } + case SGL_CMD_PROGRAMBINARY: { + int program = *pb++; + int binaryFormat = *pb++; + int length = *pb++; + void *binary = pb; + pb += CEIL_DIV(length, 4); + + glProgramBinary(program, binaryFormat, binary, length); + break; + } + case SGL_CMD_CREATESHADERPROGRAMV: { + int type = *pb++; + int count = *pb++; + + *(int*)(p + SGL_OFFSET_REGISTER_RETVAL) = 0; + break; + } + case SGL_CMD_DELETEPROGRAMPIPELINES: { + unsigned int buffer = *pb++; + glDeleteProgramPipelines(1, &buffer); + break; + } + case SGL_CMD_GENPROGRAMPIPELINES: { + glGenProgramPipelines(1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_GETPROGRAMPIPELINEIV: { + int pipeline = *pb++; + int pname = *pb++; + glGetProgramPipelineiv(pipeline, pname, p + SGL_OFFSET_REGISTER_RETVAL); + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX2FV: { + int program = *pb++, + location = *pb++, + count = *pb++, + transpose = *pb++; + glProgramUniformMatrix2fv(program, location, count, transpose, uploaded); + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX3FV: { + int program = *pb++, + location = *pb++, + count = *pb++, + transpose = *pb++; + glProgramUniformMatrix3fv(program, location, count, transpose, uploaded); + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX4FV: { + int program = *pb++, + location = *pb++, + count = *pb++, + transpose = *pb++; + glProgramUniformMatrix4fv(program, location, count, transpose, uploaded); + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX2DV: { + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX3DV: { + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX4DV: { + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX2X3FV: { + int program = *pb++, + location = *pb++, + count = *pb++, + transpose = *pb++; + glProgramUniformMatrix2x3fv(program, location, count, transpose, uploaded); + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX3X2FV: { + int program = *pb++, + location = *pb++, + count = *pb++, + transpose = *pb++; + glProgramUniformMatrix3x2fv(program, location, count, transpose, uploaded); + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX2X4FV: { + int program = *pb++, + location = *pb++, + count = *pb++, + transpose = *pb++; + glProgramUniformMatrix2x4fv(program, location, count, transpose, uploaded); + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX4X2FV: { + int program = *pb++, + location = *pb++, + count = *pb++, + transpose = *pb++; + glProgramUniformMatrix4x2fv(program, location, count, transpose, uploaded); + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX3X4FV: { + int program = *pb++, + location = *pb++, + count = *pb++, + transpose = *pb++; + glProgramUniformMatrix3x4fv(program, location, count, transpose, uploaded); + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX4X3FV: { + int program = *pb++, + location = *pb++, + count = *pb++, + transpose = *pb++; + glProgramUniformMatrix4x3fv(program, location, count, transpose, uploaded); + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX2X3DV: { + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX3X2DV: { + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX2X4DV: { + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX4X2DV: { + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX3X4DV: { + break; + } + case SGL_CMD_PROGRAMUNIFORMMATRIX4X3DV: { + break; + } + case SGL_CMD_GETPROGRAMPIPELINEINFOLOG: { + int pipeline = *pb++; + int bufSize = *pb++; + glGetProgramPipelineInfoLog(pipeline, bufSize, + p + SGL_OFFSET_REGISTER_RETVAL_V, + p + SGL_OFFSET_REGISTER_RETVAL_V + sizeof(GLsizei) + ); + break; + } + case SGL_CMD_VERTEXATTRIBLPOINTER: { + int index = *pb++, + size = *pb++, + type = *pb++, + stride = *pb++, + ptr = *pb++; + glVertexAttribLPointer(index, size, type, stride, !is_value_likely_an_offset((void*)(uintptr_t)ptr) ? uploaded : (void*)(uintptr_t)ptr); + break; + } + case SGL_CMD_VIEWPORTARRAYV: { + int first = *pb++; + int count = *pb++; + glViewportArrayv(first, count, uploaded); + break; + } + case SGL_CMD_VIEWPORTINDEXEDFV: { + break; + } + case SGL_CMD_SCISSORARRAYV: { + int first = *pb++; + int count = *pb++; + glScissorArrayv(first, count, uploaded); + break; + } + case SGL_CMD_SCISSORINDEXEDV: { + glScissorIndexedv(*pb++, uploaded); + break; + } + case SGL_CMD_DEPTHRANGEARRAYV: { + int first = *pb++; + int count = *pb++; + glDepthRangeArrayv(first, count, uploaded); + break; + } + case SGL_CMD_GETFLOATI_V: { + float v[16]; + int target = *pb++, + index = *pb++; + glGetFloati_v(target, index, v); + memcpy(p + SGL_OFFSET_REGISTER_RETVAL_V, v, sizeof(float) * 16); + break; + } + case SGL_CMD_GETDOUBLEI_V: { + double v[16]; + int target = *pb++, + index = *pb++; + glGetDoublei_v(target, index, v); + memcpy(p + SGL_OFFSET_REGISTER_RETVAL_V, v, sizeof(double) * 16); + break; + } + case SGL_CMD_DRAWELEMENTSINSTANCEDBASEINSTANCE: { + int mode = *pb++; + int count = *pb++; + int type = *pb++; + int indices = *pb++; + int instancecount = *pb++; + int baseinstance = *pb++; + glDrawElementsInstancedBaseInstance(mode, count, type, (void*)(uintptr_t)indices, instancecount, baseinstance); + break; + } + case SGL_CMD_DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE: { + int mode = *pb++; + int count = *pb++; + int type = *pb++; + int indices = *pb++; + int instancecount = *pb++; + int basevertex = *pb++; + int baseinstance = *pb++; + glDrawElementsInstancedBaseVertexBaseInstance(mode, count, type, (void*)(uintptr_t)indices, instancecount, basevertex, baseinstance); + break; + } + case SGL_CMD_GETINTERNALFORMATIV: { + break; + } + case SGL_CMD_GETACTIVEATOMICCOUNTERBUFFERIV: { + int program = *pb++; + int bufferIndex = *pb++; + int pname = *pb++; + + if (pname == GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES) { + glGetActiveAtomicCounterBufferiv(program, bufferIndex, GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS, (int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + glGetActiveAtomicCounterBufferiv(program, bufferIndex, GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES, (int*)(p + SGL_OFFSET_REGISTER_RETVAL_V)); + } else { + glGetActiveAtomicCounterBufferiv(program, bufferIndex, pname, (int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + } + + break; + } + case SGL_CMD_CLEARBUFFERDATA: { + int target = *pb++; + int internalformat = *pb++; + int format = *pb++; + int type = *pb++; + unsigned int data = *pb++; + glClearBufferData(target, internalformat, format, type, &data); + break; + } + case SGL_CMD_CLEARBUFFERSUBDATA: { + int target = *pb++; + int internalformat = *pb++; + int offset = *pb++; + int size = *pb++; + int format = *pb++; + int type = *pb++; + unsigned int data = *pb++; + glClearBufferSubData(target, internalformat, offset, size, format, type, &data); + break; + } + case SGL_CMD_GETFRAMEBUFFERPARAMETERIV: { + int target = *pb++; + int pname = *pb++; + glGetFramebufferParameteriv(target, pname, p + SGL_OFFSET_REGISTER_RETVAL); + break; + } + case SGL_CMD_GETINTERNALFORMATI64V: { + break; + } + case SGL_CMD_INVALIDATEFRAMEBUFFER: { + int target = *pb++; + int numAttachments = *pb++; + glInvalidateFramebuffer(target, numAttachments, uploaded); + break; + } + case SGL_CMD_INVALIDATESUBFRAMEBUFFER: { + int target = *pb++; + int numAttachments = *pb++; + int x = *pb++; + int y = *pb++; + int width = *pb++; + int height = *pb++; + glInvalidateSubFramebuffer(target, numAttachments, uploaded, x, y, width, height); + break; + } + case SGL_CMD_MULTIDRAWARRAYSINDIRECT: { + break; + } + case SGL_CMD_MULTIDRAWELEMENTSINDIRECT: { + break; + } + case SGL_CMD_GETPROGRAMINTERFACEIV: { + int program = *pb++; + int programInterface = *pb++; + int pname = *pb++; + glGetProgramInterfaceiv(program, programInterface, pname, p + SGL_OFFSET_REGISTER_RETVAL); + break; + } + case SGL_CMD_GETPROGRAMRESOURCEINDEX: { + int program = *pb++; + int programInterface = *pb++; + char *name = (char*)pb; + ADVANCE_PAST_STRING(); + *(int*)(p + SGL_OFFSET_REGISTER_RETVAL) = glGetProgramResourceIndex(program, programInterface, name); + break; + } + case SGL_CMD_GETPROGRAMRESOURCENAME: { + int program = *pb++; + int programInterface = *pb++; + int index = *pb++; + int bufSize = *pb++; + glGetProgramResourceName(program, programInterface, index, bufSize, + p + SGL_OFFSET_REGISTER_RETVAL_V, + p + SGL_OFFSET_REGISTER_RETVAL_V + sizeof(GLsizei) + ); + break; + } + case SGL_CMD_GETPROGRAMRESOURCEIV: { + int program = *pb++; + int programInterface = *pb++; + int index = *pb++; + int propCount = *pb++; + int bufSize = *pb++; + glGetProgramResourceiv(program, programInterface, index, propCount, uploaded, bufSize, + p + SGL_OFFSET_REGISTER_RETVAL_V, + p + SGL_OFFSET_REGISTER_RETVAL_V + sizeof(GLsizei) + ); + break; + } + case SGL_CMD_GETPROGRAMRESOURCELOCATION: { + int program = *pb++; + int programInterface = *pb++; + char *name = (char*)pb; + ADVANCE_PAST_STRING(); + + *(int*)(p + SGL_OFFSET_REGISTER_RETVAL) = glGetProgramResourceLocation(program, programInterface, name); + break; + } + case SGL_CMD_GETPROGRAMRESOURCELOCATIONINDEX: { + int program = *pb++; + int programInterface = *pb++; + char *name = (char*)pb; + ADVANCE_PAST_STRING(); + + *(int*)(p + SGL_OFFSET_REGISTER_RETVAL) = glGetProgramResourceLocationIndex(program, programInterface, name); + break; + } + case SGL_CMD_DEBUGMESSAGECONTROL: { + break; + } + case SGL_CMD_DEBUGMESSAGEINSERT: { + break; + } + case SGL_CMD_DEBUGMESSAGECALLBACK: { + break; + } + case SGL_CMD_GETDEBUGMESSAGELOG: { + break; + } + case SGL_CMD_PUSHDEBUGGROUP: { + break; + } + case SGL_CMD_OBJECTLABEL: { + break; + } + case SGL_CMD_GETOBJECTLABEL: { + break; + } + case SGL_CMD_OBJECTPTRLABEL: { + break; + } + case SGL_CMD_GETOBJECTPTRLABEL: { + break; + } + case SGL_CMD_BUFFERSTORAGE: { + int target = *pb++, + size = *pb++, + use_uploaded = *pb++, + usage = *pb++; + glBufferData(target, size, use_uploaded ? uploaded : NULL, usage); + break; + } + case SGL_CMD_CLEARTEXIMAGE: { + int texture = *pb++; + int level = *pb++; + int format = *pb++; + int type = *pb++; + unsigned int data = *pb++; + glClearTexImage(texture, level, format, type, &data); + break; + } + case SGL_CMD_CLEARTEXSUBIMAGE: { + int texture = *pb++; + int level = *pb++; + int xoffset = *pb++; + int yoffset = *pb++; + int zoffset = *pb++; + int width = *pb++; + int height = *pb++; + int depth = *pb++; + int format = *pb++; + int type = *pb++; + unsigned int data = *pb++; + glClearTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, &data); + break; + } + case SGL_CMD_BINDBUFFERSRANGE: { + int target = *pb++; + int first = *pb++; + int count = *pb++; + // to-do: possibly optimize by just setting these to point into pb + GLuint buffers[count]; + GLintptr offsets[count]; + GLsizeiptr sizes[count]; + for (int i = 0; i < count; i++) { + buffers[i] = *pb++; + offsets[i] = *pb++; + sizes[i] = *pb++; + } + glBindBuffersRange(target, first, count, buffers, offsets, sizes); + break; + } + case SGL_CMD_BINDTEXTURES: { + int first = *pb++; + int count = *pb++; + glBindTextures(first, count, uploaded); + break; + } + case SGL_CMD_BINDSAMPLERS: { + int first = *pb++; + int count = *pb++; + glBindSamplers(first, count, uploaded); + break; + } + case SGL_CMD_BINDIMAGETEXTURES: { + int first = *pb++; + int count = *pb++; + glBindImageTextures(first, count, uploaded); + break; + } + case SGL_CMD_BINDVERTEXBUFFERS: { + int first = *pb++; + int count = *pb++; + // to-do: possibly optimize by just setting these to point into pb + GLuint buffers[count]; + GLintptr offsets[count]; + GLsizei strides[count]; + for (int i = 0; i < count; i++) { + buffers[i] = *pb++; + offsets[i] = *pb++; + strides[i] = *pb++; + } + glBindVertexBuffers(first, count, buffers, offsets, strides); + break; + } + case SGL_CMD_CREATETRANSFORMFEEDBACKS: { + glCreateTransformFeedbacks(1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_GETTRANSFORMFEEDBACKIV: { + break; + } + case SGL_CMD_GETTRANSFORMFEEDBACKI_V: { + break; + } + case SGL_CMD_GETTRANSFORMFEEDBACKI64_V: { + break; + } + case SGL_CMD_CREATEBUFFERS: { + glCreateBuffers(1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_NAMEDBUFFERSTORAGE: { + break; + } + case SGL_CMD_NAMEDBUFFERDATA: { + break; + } + case SGL_CMD_NAMEDBUFFERSUBDATA: { + break; + } + case SGL_CMD_CLEARNAMEDBUFFERDATA: { + break; + } + case SGL_CMD_CLEARNAMEDBUFFERSUBDATA: { + break; + } + case SGL_CMD_MAPNAMEDBUFFER: { + break; + } + case SGL_CMD_MAPNAMEDBUFFERRANGE: { + break; + } + case SGL_CMD_GETNAMEDBUFFERPARAMETERIV: { + break; + } + case SGL_CMD_GETNAMEDBUFFERPARAMETERI64V: { + break; + } + case SGL_CMD_GETNAMEDBUFFERPOINTERV: { + break; + } + case SGL_CMD_GETNAMEDBUFFERSUBDATA: { + break; + } + case SGL_CMD_CREATEFRAMEBUFFERS: { + glCreateFramebuffers(1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_NAMEDFRAMEBUFFERDRAWBUFFERS: { + break; + } + case SGL_CMD_INVALIDATENAMEDFRAMEBUFFERDATA: { + break; + } + case SGL_CMD_INVALIDATENAMEDFRAMEBUFFERSUBDATA: { + break; + } + case SGL_CMD_CLEARNAMEDFRAMEBUFFERIV: { + break; + } + case SGL_CMD_CLEARNAMEDFRAMEBUFFERUIV: { + break; + } + case SGL_CMD_CLEARNAMEDFRAMEBUFFERFV: { + break; + } + case SGL_CMD_GETNAMEDFRAMEBUFFERPARAMETERIV: { + break; + } + case SGL_CMD_GETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIV: { + break; + } + case SGL_CMD_CREATERENDERBUFFERS: { + glCreateRenderbuffers(1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_GETNAMEDRENDERBUFFERPARAMETERIV: { + break; + } + case SGL_CMD_CREATETEXTURES: { + glCreateTextures(*pb++, 1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_TEXTURESUBIMAGE1D: { + break; + } + case SGL_CMD_TEXTURESUBIMAGE3D: { + break; + } + case SGL_CMD_COMPRESSEDTEXTURESUBIMAGE1D: { + break; + } + case SGL_CMD_COMPRESSEDTEXTURESUBIMAGE2D: { + break; + } + case SGL_CMD_COMPRESSEDTEXTURESUBIMAGE3D: { + break; + } + case SGL_CMD_TEXTUREPARAMETERFV: { + break; + } + case SGL_CMD_TEXTUREPARAMETERIIV: { + break; + } + case SGL_CMD_TEXTUREPARAMETERIUIV: { + break; + } + case SGL_CMD_TEXTUREPARAMETERIV: { + break; + } + case SGL_CMD_GETTEXTUREIMAGE: { + break; + } + case SGL_CMD_GETCOMPRESSEDTEXTUREIMAGE: { + break; + } + case SGL_CMD_GETTEXTURELEVELPARAMETERFV: { + break; + } + case SGL_CMD_GETTEXTURELEVELPARAMETERIV: { + break; + } + case SGL_CMD_GETTEXTUREPARAMETERFV: { + break; + } + case SGL_CMD_GETTEXTUREPARAMETERIIV: { + break; + } + case SGL_CMD_GETTEXTUREPARAMETERIUIV: { + break; + } + case SGL_CMD_GETTEXTUREPARAMETERIV: { + break; + } + case SGL_CMD_CREATEVERTEXARRAYS: { + glCreateVertexArrays(1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_VERTEXARRAYVERTEXBUFFERS: { + break; + } + case SGL_CMD_GETVERTEXARRAYIV: { + break; + } + case SGL_CMD_GETVERTEXARRAYINDEXEDIV: { + break; + } + case SGL_CMD_GETVERTEXARRAYINDEXED64IV: { + break; + } + case SGL_CMD_CREATESAMPLERS: { + glCreateSamplers(1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_CREATEPROGRAMPIPELINES: { + glCreateProgramPipelines(1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_CREATEQUERIES: { + glCreateQueries(*pb++, 1, (unsigned int*)(p + SGL_OFFSET_REGISTER_RETVAL)); + break; + } + case SGL_CMD_GETTEXTURESUBIMAGE: { + break; + } + case SGL_CMD_GETCOMPRESSEDTEXTURESUBIMAGE: { + break; + } + case SGL_CMD_GETNCOMPRESSEDTEXIMAGE: { + break; + } + case SGL_CMD_GETNTEXIMAGE: { + break; + } + case SGL_CMD_GETNUNIFORMDV: { + break; + } + case SGL_CMD_GETNUNIFORMFV: { + break; + } + case SGL_CMD_GETNUNIFORMIV: { + break; + } + case SGL_CMD_GETNUNIFORMUIV: { + break; + } + case SGL_CMD_READNPIXELS: { + break; + } + case SGL_CMD_GETNMAPDV: { + break; + } + case SGL_CMD_GETNMAPFV: { + break; + } + case SGL_CMD_GETNMAPIV: { + break; + } + case SGL_CMD_GETNPIXELMAPFV: { + break; + } + case SGL_CMD_GETNPIXELMAPUIV: { + break; + } + case SGL_CMD_GETNPIXELMAPUSV: { + break; + } + case SGL_CMD_GETNPOLYGONSTIPPLE: { + break; + } + case SGL_CMD_GETNCOLORTABLE: { + break; + } + case SGL_CMD_GETNCONVOLUTIONFILTER: { + break; + } + case SGL_CMD_GETNSEPARABLEFILTER: { + break; + } + case SGL_CMD_GETNHISTOGRAM: { + break; + } + case SGL_CMD_GETNMINMAX: { + break; + } + case SGL_CMD_GETSTRING: { + const unsigned char *string = glGetString(*pb++); + int length = strlen((char*)string); + memcpy(p + SGL_OFFSET_REGISTER_RETVAL_V, string, length); + memcpy(p + SGL_OFFSET_REGISTER_RETVAL, &length, sizeof(int)); + break; + } } if (!begun) {