ctx->num_compressed_texture_formats = 0;
+ ctx->pack_depth_stencil = false;
+
+ ctx->texture_npot = false;
+
+ ctx->texture_rectangle = false;
+
+ ctx->texture_filter_anisotropic = false;
+
ctx->active_texture_unit = 0;
ctx->vbo = NULL;
int num_texture_units)
{
int i;
+ const char *extensions;
if (num_texture_units < 1) {
num_texture_units = 1;
GL_NUM_COMPRESSED_TEXTURE_FORMATS,
&ctx->num_compressed_texture_formats);
+ extensions = (const char*)ctx->driver_ps->GetString(ctx->driver_ps, GL_EXTENSIONS);
+
+ ctx->pack_depth_stencil = (strstr(extensions, "GL_EXT_packed_depth_stencil ") != NULL);
+
+ ctx->texture_npot = (strstr(extensions, "GL_OES_texture_npot ") != NULL) ||
+ (strstr(extensions, "GL_ARB_texture_non_power_of_two ") != NULL);
+
+ ctx->texture_rectangle = (strstr(extensions, "GL_NV_texture_rectangle ") != NULL) ||
+ (strstr(extensions, "GL_EXT_texture_rectangle ") != NULL) ||
+ (strstr(extensions, "GL_ARB_texture_rectangle ") != NULL);
+
+ ctx->texture_filter_anisotropic = (strstr(extensions, "GL_EXT_texture_filter_anisotropic ") != NULL);
+
YAGL_LOG_FUNC_EXIT(NULL);
}
GLenum /*pname*/,
GLfloat */*params*/);
+ GLchar *(*get_extensions)(struct yagl_gles_context */*ctx*/);
+
+ void (*pre_draw)(struct yagl_gles_context */*ctx*/, GLenum mode);
+
+ void (*post_draw)(struct yagl_gles_context */*ctx*/, GLenum mode);
+
/*
* Pixel Buffer Object (PBO) for quick access to current surface pixels.
* 'read_pixels' will automatically detect surface size changes and
int num_compressed_texture_formats;
+ bool pack_depth_stencil;
+
+ bool texture_npot;
+
+ bool texture_rectangle;
+
+ bool texture_filter_anisotropic;
+
int active_texture_unit;
struct yagl_gles_buffer *vbo;
return;
}
+ ctx->pre_draw(ctx, mode);
+
ctx->driver_ps->DrawArrays(ctx->driver_ps, mode, first, count);
+
+ ctx->post_draw(ctx, mode);
}
void yagl_host_glDrawElements(GLenum mode,
goto out;
}
+ ctx->pre_draw(ctx, mode);
+
ctx->driver_ps->DrawElements(ctx->driver_ps,
mode,
count,
type,
(ctx->ebo ? (GLvoid*)indices_ : indices));
+ ctx->post_draw(ctx, mode);
+
out:
if (ebo_bound) {
ctx->driver_ps->BindBuffer(ctx->driver_ps,
ctx->driver_ps->Viewport(ctx->driver_ps, x, y, width, height);
}
+
+GLuint yagl_host_glGetExtensionStringYAGL(target_ulong /* GLchar* */ str_)
+{
+ GLchar *str;
+ GLuint str_len;
+
+ YAGL_GET_CTX_RET(glGetExtensionStringYAGL, 1);
+
+ str = ctx->get_extensions(ctx);
+
+ str_len = strlen(str);
+
+ if (str_) {
+ yagl_mem_put(ts, str_, str_len + 1, str);
+ }
+
+ g_free(str);
+
+ return str_len + 1;
+}
GLint y,
GLsizei width,
GLsizei height);
+GLuint yagl_host_glGetExtensionStringYAGL(target_ulong /* GLchar* */ str_);
#endif
return out_buff;
}
-const uint32_t yagl_gles1_api_num_funcs = 143;
+/*
+ * glGetExtensionStringYAGL dispatcher. id = 144
+ */
+static uint8_t* yagl_func_glGetExtensionStringYAGL(struct yagl_thread_state *ts,
+ uint8_t *out_buff,
+ uint8_t *in_buff)
+{
+ target_ulong str = yagl_marshal_get_ptr(&out_buff);
+ YAGL_LOG_FUNC_ENTER_SPLIT1(ts->ps->id, ts->id, glGetExtensionStringYAGL, target_ulong, str);
+ GLuint ret = yagl_host_glGetExtensionStringYAGL(str);
+ YAGL_LOG_FUNC_EXIT_SPLIT(GLuint, ret);
+ yagl_marshal_put_GLuint(&in_buff, ret);
+ return out_buff;
+}
+
+const uint32_t yagl_gles1_api_num_funcs = 144;
yagl_api_func yagl_gles1_api_funcs[] = {
&yagl_func_glAlphaFunc,
&yagl_func_glTexSubImage2D,
&yagl_func_glTranslatex,
&yagl_func_glVertexPointer,
- &yagl_func_glViewport
+ &yagl_func_glViewport,
+ &yagl_func_glGetExtensionStringYAGL
};
return out_buff;
}
-const uint32_t yagl_gles2_api_num_funcs = 141;
+/*
+ * glGetExtensionStringYAGL dispatcher. id = 142
+ */
+static uint8_t* yagl_func_glGetExtensionStringYAGL(struct yagl_thread_state *ts,
+ uint8_t *out_buff,
+ uint8_t *in_buff)
+{
+ target_ulong str = yagl_marshal_get_ptr(&out_buff);
+ YAGL_LOG_FUNC_ENTER_SPLIT1(ts->ps->id, ts->id, glGetExtensionStringYAGL, target_ulong, str);
+ GLuint ret = yagl_host_glGetExtensionStringYAGL(str);
+ YAGL_LOG_FUNC_EXIT_SPLIT(GLuint, ret);
+ yagl_marshal_put_GLuint(&in_buff, ret);
+ return out_buff;
+}
+
+const uint32_t yagl_gles2_api_num_funcs = 142;
yagl_api_func yagl_gles2_api_funcs[] = {
&yagl_func_glActiveTexture,
&yagl_func_glVertexAttrib4f,
&yagl_func_glVertexAttrib4fv,
&yagl_func_glVertexAttribPointer,
- &yagl_func_glViewport
+ &yagl_func_glViewport,
+ &yagl_func_glGetExtensionStringYAGL
};
#include <GLES2/gl2ext.h>
#include "yagl_gles2_driver.h"
+/*
+ * We can't include GL/glext.h here
+ */
+#define GL_POINT_SPRITE 0x8861
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+
static void yagl_gles2_array_apply(struct yagl_gles_array *array)
{
struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)array->ctx;
case GL_UNPACK_ALIGNMENT: *count = 1; break;
case GL_VIEWPORT: *count = 4; break;
case GL_MAX_SAMPLES_IMG: *count = 1; break;
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: *count = 1; break;
default: return false;
}
return true;
return true;
}
+static GLchar *yagl_gles2_context_get_extensions(struct yagl_gles_context *ctx)
+{
+ struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
+
+ const GLchar *mandatory_extensions =
+ "GL_OES_depth24 GL_OES_depth32 "
+ "GL_OES_texture_float GL_OES_texture_float_linear "
+ "GL_OES_depth_texture ";
+ const GLchar *pack_depth_stencil = "GL_OES_packed_depth_stencil ";
+ const GLchar *texture_npot = "GL_OES_texture_npot ";
+ const GLchar *texture_rectangle = "GL_ARB_texture_rectangle ";
+ const GLchar *texture_filter_anisotropic = "GL_EXT_texture_filter_anisotropic ";
+ const GLchar *texture_half_float = "GL_OES_texture_half_float GL_OES_texture_half_float_linear ";
+ const GLchar *vertex_half_float = "GL_OES_vertex_half_float ";
+ const GLchar *standard_derivatives = "GL_OES_standard_derivatives ";
+
+ GLuint len = strlen(mandatory_extensions);
+ GLchar *str;
+
+ if (gles2_ctx->base.pack_depth_stencil) {
+ len += strlen(pack_depth_stencil);
+ }
+
+ if (gles2_ctx->base.texture_npot) {
+ len += strlen(texture_npot);
+ }
+
+ if (gles2_ctx->base.texture_rectangle) {
+ len += strlen(texture_rectangle);
+ }
+
+ if (gles2_ctx->base.texture_filter_anisotropic) {
+ len += strlen(texture_filter_anisotropic);
+ }
+
+ if (gles2_ctx->texture_half_float) {
+ len += strlen(texture_half_float);
+ }
+
+ if (gles2_ctx->vertex_half_float) {
+ len += strlen(vertex_half_float);
+ }
+
+ if (gles2_ctx->standard_derivatives) {
+ len += strlen(standard_derivatives);
+ }
+
+ str = g_malloc0(len + 1);
+
+ strcpy(str, mandatory_extensions);
+
+ if (gles2_ctx->base.pack_depth_stencil) {
+ strcat(str, pack_depth_stencil);
+ }
+
+ if (gles2_ctx->base.texture_npot) {
+ strcat(str, texture_npot);
+ }
+
+ if (gles2_ctx->base.texture_rectangle) {
+ strcat(str, texture_rectangle);
+ }
+
+ if (gles2_ctx->base.texture_filter_anisotropic) {
+ strcat(str, texture_filter_anisotropic);
+ }
+
+ if (gles2_ctx->texture_half_float) {
+ strcat(str, texture_half_float);
+ }
+
+ if (gles2_ctx->vertex_half_float) {
+ strcat(str, vertex_half_float);
+ }
+
+ if (gles2_ctx->standard_derivatives) {
+ strcat(str, standard_derivatives);
+ }
+
+ return str;
+}
+
+static void yagl_gles2_context_pre_draw(struct yagl_gles_context *ctx, GLenum mode)
+{
+ /*
+ * Enable texture generation for GL_POINTS and gl_PointSize shader variable.
+ * GLESv2 assumes this is enabled by default, we need to set this
+ * state for GL.
+ */
+
+ if (mode == GL_POINTS) {
+ ctx->driver_ps->Enable(ctx->driver_ps, GL_POINT_SPRITE);
+ ctx->driver_ps->Enable(ctx->driver_ps, GL_VERTEX_PROGRAM_POINT_SIZE);
+ }
+}
+
+static void yagl_gles2_context_post_draw(struct yagl_gles_context *ctx, GLenum mode)
+{
+ if (mode == GL_POINTS) {
+ ctx->driver_ps->Disable(ctx->driver_ps, GL_VERTEX_PROGRAM_POINT_SIZE);
+ ctx->driver_ps->Disable(ctx->driver_ps, GL_POINT_SPRITE);
+ }
+}
+
static void yagl_gles2_context_destroy(struct yagl_client_context *ctx)
{
struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
struct yagl_gles_driver_ps *gles_driver = gles2_ctx->driver_ps->common;
GLint i, num_arrays = 0, num_texture_units = 0;
struct yagl_gles_array *arrays;
+ const char *extensions;
YAGL_LOG_FUNC_ENTER_TS(ts,
yagl_gles2_context_prepare,
GL_NUM_SHADER_BINARY_FORMATS,
&gles2_ctx->num_shader_binary_formats);
+ extensions = (const char*)gles_driver->GetString(gles_driver, GL_EXTENSIONS);
+
+ gles2_ctx->texture_half_float = (strstr(extensions, "GL_ARB_half_float_pixel ") != NULL) ||
+ (strstr(extensions, "GL_NV_half_float ") != NULL);
+
+ gles2_ctx->vertex_half_float = (strstr(extensions, "GL_ARB_half_float_vertex ") != NULL);
+
+ gles2_ctx->standard_derivatives = (strstr(extensions, "GL_OES_standard_derivatives ") != NULL);
+
YAGL_LOG_FUNC_EXIT(NULL);
}
gles2_ctx->base.get_booleanv = &yagl_gles2_context_get_booleanv;
gles2_ctx->base.get_integerv = &yagl_gles2_context_get_integerv;
gles2_ctx->base.get_floatv = &yagl_gles2_context_get_floatv;
+ gles2_ctx->base.get_extensions = &yagl_gles2_context_get_extensions;
+ gles2_ctx->base.pre_draw = &yagl_gles2_context_pre_draw;
+ gles2_ctx->base.post_draw = &yagl_gles2_context_post_draw;
gles2_ctx->driver_ps = driver_ps;
gles2_ctx->prepared = false;
gles2_ctx->num_shader_binary_formats = 0;
+ gles2_ctx->texture_half_float = false;
+ gles2_ctx->vertex_half_float = false;
+ gles2_ctx->standard_derivatives = false;
+
gles2_ctx->program_local_name = 0;
YAGL_LOG_FUNC_EXIT("%p", gles2_ctx);
int num_shader_binary_formats;
+ bool texture_half_float;
+
+ bool vertex_half_float;
+
+ bool standard_derivatives;
+
yagl_object_name program_local_name;
};
YAGL_GLES_OGL_PROC4(glFramebufferRenderbufferEXT, GLenum, GLenum, GLenum, GLuint, target, attachment, renderbuffertarget, renderbuffer)
YAGL_GLES_OGL_PROC_RET1(GLenum, glCheckFramebufferStatusEXT, GLenum, target)
YAGL_GLES_OGL_PROC1(glGenerateMipmapEXT, GLenum, target)
+ YAGL_GLES_OGL_PROC_RET1(const GLubyte*, glGetString, GLenum, name)
};
YAGL_GLES_OGL_PROC_IMPL1(yagl_gles_driver_ps, yagl_gles_ogl_ps, yagl_gles_ogl, ActiveTexture, GLenum, texture)
YAGL_GLES_OGL_PROC_IMPL4(yagl_gles_driver_ps, yagl_gles_ogl_ps, yagl_gles_ogl, FramebufferRenderbufferEXT, GLenum, GLenum, GLenum, GLuint, target, attachment, renderbuffertarget, renderbuffer)
YAGL_GLES_OGL_PROC_IMPL_RET1(yagl_gles_driver_ps, yagl_gles_ogl_ps, yagl_gles_ogl, GLenum, CheckFramebufferStatusEXT, GLenum, target)
YAGL_GLES_OGL_PROC_IMPL1(yagl_gles_driver_ps, yagl_gles_ogl_ps, yagl_gles_ogl, GenerateMipmapEXT, GLenum, target)
+YAGL_GLES_OGL_PROC_IMPL_RET1(yagl_gles_driver_ps, yagl_gles_ogl_ps, yagl_gles_ogl, const GLubyte*, GetString, GLenum, name)
struct yagl_gles_ogl_ps
*yagl_gles_ogl_ps_create(struct yagl_gles_ogl *gles_ogl,
gles_ogl_ps->base.FramebufferRenderbuffer = &yagl_gles_ogl_FramebufferRenderbufferEXT;
gles_ogl_ps->base.CheckFramebufferStatus = &yagl_gles_ogl_CheckFramebufferStatusEXT;
gles_ogl_ps->base.GenerateMipmap = &yagl_gles_ogl_GenerateMipmapEXT;
+ YAGL_GLES_OGL_ASSIGN_PROC(yagl_gles_ogl, gles_ogl_ps, GetString);
YAGL_LOG_FUNC_EXIT(NULL);
YAGL_GLES_OGL_GET_PROC(gles_ogl, glFramebufferRenderbufferEXT);
YAGL_GLES_OGL_GET_PROC(gles_ogl, glCheckFramebufferStatusEXT);
YAGL_GLES_OGL_GET_PROC(gles_ogl, glGenerateMipmapEXT);
+ YAGL_GLES_OGL_GET_PROC(gles_ogl, glGetString);
YAGL_LOG_FUNC_EXIT(NULL);
YAGL_GLES_DRIVER_FUNC4(struct yagl_gles_driver_ps *driver_ps, FramebufferRenderbuffer, GLenum, GLenum, GLenum, GLuint, target, attachment, renderbuffertarget, renderbuffer)
YAGL_GLES_DRIVER_FUNC_RET1(struct yagl_gles_driver_ps *driver_ps, GLenum, CheckFramebufferStatus, GLenum, target)
YAGL_GLES_DRIVER_FUNC1(struct yagl_gles_driver_ps *driver_ps, GenerateMipmap, GLenum, target)
+ YAGL_GLES_DRIVER_FUNC_RET1(struct yagl_gles_driver_ps *driver_ps, const GLubyte*, GetString, GLenum, name)
};
void yagl_gles_driver_ps_init(struct yagl_gles_driver_ps *driver_ps,
/*
* Whenever protocol changes be sure to bump this.
*/
-#define YAGL_VERSION 7
+#define YAGL_VERSION 8
#endif