diff --git a/media-layer/gles/src/passthrough.cpp b/media-layer/gles/src/passthrough.cpp index eede57cc03..c9935bf83a 100644 --- a/media-layer/gles/src/passthrough.cpp +++ b/media-layer/gles/src/passthrough.cpp @@ -246,6 +246,26 @@ GL_FUNC(glLightModelfv, void, (GLenum pname, const GLfloat *params)) void media_glLightModelfv(const GLenum pname, const GLfloat *params) { real_glLightModelfv()(pname, params); } +GL_FUNC(glGenQueries, void, (GLsizei n, GLuint *ids)) +void media_glGenQueries(const GLsizei n, GLuint *ids) { + real_glGenQueries()(n, ids); +} +GL_FUNC(glDeleteQueries, void, (GLsizei n, const GLuint *ids)) +void media_glDeleteQueries(const GLsizei n, const GLuint *ids) { + real_glDeleteQueries()(n, ids); +} +GL_FUNC(glBeginQuery, void, (GLenum target, GLuint id)) +void media_glBeginQuery(const GLenum target, const GLuint id) { + real_glBeginQuery()(target, id); +} +GL_FUNC(glEndQuery, void, (GLenum target)) +void media_glEndQuery(const GLenum target) { + real_glEndQuery()(target); +} +GL_FUNC(glGetQueryObjectuiv, void, (GLuint id, GLenum pname, GLuint *params)) +void media_glGetQueryObjectuiv(const GLuint id, const GLenum pname, GLuint *params) { + real_glGetQueryObjectuiv()(id, pname, params); +} // GL_EXT_multi_draw_arrays GL_FUNC(glMultiDrawArraysEXT, void, (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount)) diff --git a/media-layer/include/GLES/gl.h b/media-layer/include/GLES/gl.h index aa192f3f20..c90ac886bf 100644 --- a/media-layer/include/GLES/gl.h +++ b/media-layer/include/GLES/gl.h @@ -100,6 +100,9 @@ extern "C" { #define GL_AMBIENT_AND_DIFFUSE 0x1602 #define GL_LIGHT_MODEL_AMBIENT 0xb53 #define GL_STREAM_DRAW 0x88e0 +#define GL_SAMPLES_PASSED 0x8914 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_QUERY_RESULT 0x8866 typedef float GLfloat; typedef float GLclampf; @@ -176,6 +179,11 @@ void media_glNormalPointer(GLenum type, GLsizei stride, const void *pointer); void media_glLightfv(GLenum light, GLenum pname, const GLfloat *params); void media_glColorMaterial(GLenum face, GLenum mode); void media_glLightModelfv(GLenum pname, const GLfloat *params); +void media_glGenQueries(GLsizei n, GLuint *ids); +void media_glDeleteQueries(GLsizei n, const GLuint *ids); +void media_glBeginQuery(GLenum target, GLuint id); +void media_glEndQuery(GLenum target); +void media_glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params); extern unsigned int media_context_id; diff --git a/media-layer/trampoline/src/GLESv1_CM.cpp b/media-layer/trampoline/src/GLESv1_CM.cpp index c3119e170e..d1d3548a37 100644 --- a/media-layer/trampoline/src/GLESv1_CM.cpp +++ b/media-layer/trampoline/src/GLESv1_CM.cpp @@ -871,4 +871,62 @@ CALL(75, media_glLightModelfv, void, (GLenum pname, const GLfloat *params)) func(pname, params); return 0; #endif +} + +CALL(78, media_glGenQueries, void, (GLsizei n, GLuint *ids)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(false, n, uint32_t(ids)); +#else + GLsizei n = args.next(); + GLuint *ids = new GLuint[n]; + func(n, ids); + writer(args.next(), ids, n * sizeof(GLuint)); + delete[] ids; + return 0; +#endif +} + +CALL(79, media_glDeleteQueries, void, (GLsizei n, const GLuint *ids)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(true, copy_array(n, ids)); +#else + uint32_t n; + const GLuint *ids = args.next_arr(&n); + func(GLsizei(n), ids); + return 0; +#endif +} + +CALL(80, media_glBeginQuery, void, (GLenum target, GLuint id)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(true, target, id); +#else + GLenum target = args.next(); + GLuint id = args.next(); + func(target, id); + return 0; +#endif +} + +CALL(81, media_glEndQuery, void, (GLenum target)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(true, target); +#else + GLenum target = args.next(); + func(target); + return 0; +#endif +} + +CALL(82, media_glGetQueryObjectuiv, void, (const GLuint id, GLenum pname, GLuint *params)) +#ifdef MEDIA_LAYER_TRAMPOLINE_GUEST + trampoline(false, id, pname, uint32_t(params)); +#else + GLuint id = args.next(); + GLenum pname = args.next(); + GLuint out; + func(id, pname, &out); + writer(args.next(), &out, sizeof(GLuint)); + return 0; +#endif } \ No newline at end of file diff --git a/mods/src/misc/graphics.cpp b/mods/src/misc/graphics.cpp index 8c2d2af04e..240cd73434 100644 --- a/mods/src/misc/graphics.cpp +++ b/mods/src/misc/graphics.cpp @@ -492,6 +492,14 @@ static void adjust_mov_shift(void *addr, const uint32_t new_shift) { unsigned char *x = (unsigned char *) &instruction; patch(addr, x); } +static int safe_log2(const int x) { + const double y = std::log2(x); + const int z = int(y); + if (double(z) != y) { + IMPOSSIBLE(); + } + return z; +} // Init void _init_misc_graphics() { @@ -611,8 +619,8 @@ void _init_misc_graphics() { constexpr int b = 128 / chunk_size; unsigned char render_chunk_patch_one[] = {(unsigned char) b, 0x20, 0xa0, 0xe3}; // "mov r2, #b" patch((void *) 0x4fbec, render_chunk_patch_one); - adjust_mov_shift((void *) 0x4fbfc, std::log2(b)); - const int c = std::log2(chunk_size); + adjust_mov_shift((void *) 0x4fbfc, safe_log2(b)); + const int c = safe_log2(chunk_size); adjust_mov_shift((void *) 0x4fbf0, c); adjust_mov_shift((void *) 0x4fc74, c); adjust_mov_shift((void *) 0x4fd60, c);