YaGL: Fixed a bug in glFramebufferTexture2D which didn't allow to attach cubemap textures
YaGL: Implemented remaining (rarely used) GL functions
YaGL: eglQueryAPI - moved to target
YaGL: Implemented GL_OES_EGL_image extension
YaGL: Implemented eglCreatePbufferSurface and eglCopyBuffers
}
/*
- * eglQueryAPI dispatcher. id = 11
- */
-static uint8_t* yagl_func_eglQueryAPI(struct yagl_thread_state *ts,
- uint8_t *out_buff,
- uint8_t *in_buff)
-{
- YAGL_LOG_FUNC_ENTER_SPLIT0(ts->ps->id, ts->id, eglQueryAPI);
- EGLenum ret = yagl_host_eglQueryAPI();
- YAGL_LOG_FUNC_EXIT_SPLIT(EGLenum, ret);
- yagl_marshal_put_EGLenum(&in_buff, ret);
- return out_buff;
-}
-
-/*
- * eglWaitClient dispatcher. id = 12
+ * eglWaitClient dispatcher. id = 11
*/
static uint8_t* yagl_func_eglWaitClient(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglReleaseThread dispatcher. id = 13
+ * eglReleaseThread dispatcher. id = 12
*/
static uint8_t* yagl_func_eglReleaseThread(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglCreatePbufferFromClientBuffer dispatcher. id = 14
+ * eglCreatePbufferFromClientBuffer dispatcher. id = 13
*/
static uint8_t* yagl_func_eglCreatePbufferFromClientBuffer(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglSurfaceAttrib dispatcher. id = 15
+ * eglSurfaceAttrib dispatcher. id = 14
*/
static uint8_t* yagl_func_eglSurfaceAttrib(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglBindTexImage dispatcher. id = 16
+ * eglBindTexImage dispatcher. id = 15
*/
static uint8_t* yagl_func_eglBindTexImage(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglReleaseTexImage dispatcher. id = 17
+ * eglReleaseTexImage dispatcher. id = 16
*/
static uint8_t* yagl_func_eglReleaseTexImage(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglSwapInterval dispatcher. id = 18
- */
-static uint8_t* yagl_func_eglSwapInterval(struct yagl_thread_state *ts,
- uint8_t *out_buff,
- uint8_t *in_buff)
-{
- yagl_host_handle dpy = yagl_marshal_get_host_handle(&out_buff);
- EGLint interval = yagl_marshal_get_EGLint(&out_buff);
- YAGL_LOG_FUNC_ENTER_SPLIT2(ts->ps->id, ts->id, eglSwapInterval, yagl_host_handle, EGLint, dpy, interval);
- EGLBoolean ret = yagl_host_eglSwapInterval(dpy, interval);
- YAGL_LOG_FUNC_EXIT_SPLIT(EGLBoolean, ret);
- yagl_marshal_put_EGLBoolean(&in_buff, ret);
- return out_buff;
-}
-
-/*
- * eglCreateContext dispatcher. id = 19
+ * eglCreateContext dispatcher. id = 17
*/
static uint8_t* yagl_func_eglCreateContext(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglDestroyContext dispatcher. id = 20
+ * eglDestroyContext dispatcher. id = 18
*/
static uint8_t* yagl_func_eglDestroyContext(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglMakeCurrent dispatcher. id = 21
+ * eglMakeCurrent dispatcher. id = 19
*/
static uint8_t* yagl_func_eglMakeCurrent(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglQueryContext dispatcher. id = 22
+ * eglQueryContext dispatcher. id = 20
*/
static uint8_t* yagl_func_eglQueryContext(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglWaitGL dispatcher. id = 23
+ * eglWaitGL dispatcher. id = 21
*/
static uint8_t* yagl_func_eglWaitGL(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglWaitNative dispatcher. id = 24
+ * eglWaitNative dispatcher. id = 22
*/
static uint8_t* yagl_func_eglWaitNative(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglSwapBuffers dispatcher. id = 25
+ * eglSwapBuffers dispatcher. id = 23
*/
static uint8_t* yagl_func_eglSwapBuffers(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglCopyBuffers dispatcher. id = 26
+ * eglCopyBuffers dispatcher. id = 24
*/
static uint8_t* yagl_func_eglCopyBuffers(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglCreateWindowSurfaceOffscreenYAGL dispatcher. id = 27
+ * eglCreateWindowSurfaceOffscreenYAGL dispatcher. id = 25
*/
static uint8_t* yagl_func_eglCreateWindowSurfaceOffscreenYAGL(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglCreatePbufferSurfaceOffscreenYAGL dispatcher. id = 28
+ * eglCreatePbufferSurfaceOffscreenYAGL dispatcher. id = 26
*/
static uint8_t* yagl_func_eglCreatePbufferSurfaceOffscreenYAGL(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglCreatePixmapSurfaceOffscreenYAGL dispatcher. id = 29
+ * eglCreatePixmapSurfaceOffscreenYAGL dispatcher. id = 27
*/
static uint8_t* yagl_func_eglCreatePixmapSurfaceOffscreenYAGL(struct yagl_thread_state *ts,
uint8_t *out_buff,
}
/*
- * eglResizeOffscreenSurfaceYAGL dispatcher. id = 30
+ * eglResizeOffscreenSurfaceYAGL dispatcher. id = 28
*/
static uint8_t* yagl_func_eglResizeOffscreenSurfaceYAGL(struct yagl_thread_state *ts,
uint8_t *out_buff,
return out_buff;
}
-const uint32_t yagl_egl_api_num_funcs = 30;
+const uint32_t yagl_egl_api_num_funcs = 28;
yagl_api_func yagl_egl_api_funcs[] = {
&yagl_func_eglGetError,
&yagl_func_eglDestroySurface,
&yagl_func_eglQuerySurface,
&yagl_func_eglBindAPI,
- &yagl_func_eglQueryAPI,
&yagl_func_eglWaitClient,
&yagl_func_eglReleaseThread,
&yagl_func_eglCreatePbufferFromClientBuffer,
&yagl_func_eglSurfaceAttrib,
&yagl_func_eglBindTexImage,
&yagl_func_eglReleaseTexImage,
- &yagl_func_eglSwapInterval,
&yagl_func_eglCreateContext,
&yagl_func_eglDestroyContext,
&yagl_func_eglMakeCurrent,
}
if (has_config_id) {
+ yagl_host_handle handle = 0;
struct yagl_egl_config *cfg =
yagl_egl_display_acquire_config_by_id(dpy, config_id);
- yagl_host_handle handle = cfg->res.handle;
- yagl_egl_config_release(cfg);
+
+ if (cfg) {
+ handle = cfg->res.handle;
+ yagl_egl_config_release(cfg);
+ }
YAGL_LOG_DEBUG("requesting config with id = %d", config_id);
return EGL_TRUE;
}
-EGLenum yagl_host_eglQueryAPI(void)
-{
- return egl_api_ts->api;
-}
-
EGLBoolean yagl_host_eglWaitClient(void)
{
EGLBoolean ret = EGL_FALSE;
YAGL_UNIMPLEMENTED(eglReleaseTexImage, EGL_FALSE);
}
-EGLBoolean yagl_host_eglSwapInterval(yagl_host_handle dpy,
- EGLint interval)
-{
- YAGL_UNIMPLEMENTED(eglSwapInterval, EGL_FALSE);
-}
-
yagl_host_handle yagl_host_eglCreateContext(yagl_host_handle dpy_,
yagl_host_handle config_,
yagl_host_handle share_context_,
return ret;
}
-EGLBoolean yagl_host_eglQueryContext(yagl_host_handle dpy,
- yagl_host_handle ctx,
+EGLBoolean yagl_host_eglQueryContext(yagl_host_handle dpy_,
+ yagl_host_handle ctx_,
EGLint attribute,
- target_ulong /* EGLint* */ value)
+ target_ulong /* EGLint* */ value_)
{
- YAGL_UNIMPLEMENTED(eglQueryContext, EGL_FALSE);
+ EGLBoolean ret = EGL_FALSE;
+ struct yagl_egl_display *dpy = NULL;
+ struct yagl_egl_context *ctx = NULL;
+ EGLint value = 0;
+
+ YAGL_LOG_FUNC_SET_TS(egl_api_ts->ts, eglQueryContext);
+
+ if (!yagl_validate_display(dpy_, &dpy)) {
+ goto out;
+ }
+
+ if (!yagl_validate_context(dpy, ctx_, &ctx)) {
+ goto out;
+ }
+
+ switch (attribute) {
+ case EGL_CONFIG_ID:
+ value = ctx->cfg->native.config_id;
+ break;
+ case EGL_CONTEXT_CLIENT_TYPE:
+ switch (ctx->client_ctx->client_api) {
+ case yagl_client_api_gles1:
+ case yagl_client_api_gles2:
+ value = EGL_OPENGL_ES_API;
+ break;
+ case yagl_client_api_ogl:
+ value = EGL_OPENGL_API;
+ break;
+ case yagl_client_api_ovg:
+ value = EGL_OPENVG_API;
+ break;
+ default:
+ assert(false);
+ value = EGL_NONE;
+ break;
+ }
+ break;
+ case EGL_CONTEXT_CLIENT_VERSION:
+ switch (ctx->client_ctx->client_api) {
+ case yagl_client_api_gles1:
+ value = 1;
+ break;
+ case yagl_client_api_gles2:
+ value = 2;
+ break;
+ case yagl_client_api_ogl:
+ case yagl_client_api_ovg:
+ default:
+ value = 0;
+ break;
+ }
+ break;
+ case EGL_RENDER_BUFFER:
+ if (ctx->draw) {
+ switch (ctx->draw->type) {
+ case EGL_PBUFFER_BIT:
+ case EGL_WINDOW_BIT:
+ value = EGL_BACK_BUFFER;
+ break;
+ case EGL_PIXMAP_BIT:
+ value = EGL_SINGLE_BUFFER;
+ break;
+ default:
+ assert(0);
+ value = EGL_NONE;
+ }
+ } else {
+ value = EGL_NONE;
+ }
+ break;
+ default:
+ YAGL_SET_ERR(EGL_BAD_ATTRIBUTE);
+ goto out;
+ }
+
+ if (value_) {
+ yagl_mem_put_EGLint(egl_api_ts->ts, value_, value);
+ }
+
+ ret = EGL_TRUE;
+
+out:
+ yagl_egl_context_release(ctx);
+
+ return ret;
}
EGLBoolean yagl_host_eglWaitGL(void)
{
EGLBoolean ret;
- EGLenum api = yagl_host_eglQueryAPI();
+ EGLenum api = egl_api_ts->api;
yagl_host_eglBindAPI(EGL_OPENGL_ES_API);
ret = yagl_host_eglWaitClient();
yagl_host_eglBindAPI(api);
return ret;
}
-EGLBoolean yagl_host_eglCopyBuffers(yagl_host_handle dpy,
- yagl_host_handle surface,
+EGLBoolean yagl_host_eglCopyBuffers(yagl_host_handle dpy_,
+ yagl_host_handle surface_,
EGLNativePixmapType target)
{
- YAGL_UNIMPLEMENTED(eglCopyBuffers, EGL_FALSE);
+ EGLBoolean ret = EGL_FALSE;
+ struct yagl_egl_display *dpy = NULL;
+ struct yagl_egl_surface *surface = NULL;
+
+ YAGL_LOG_FUNC_SET_TS(egl_api_ts->ts, eglCopyBuffers);
+
+ if (!yagl_validate_display(dpy_, &dpy)) {
+ goto out;
+ }
+
+ if (!yagl_validate_surface(dpy, surface_, &surface)) {
+ goto out;
+ }
+
+ if (!egl_api_ts->context) {
+ YAGL_LOG_ERROR("No current context");
+ YAGL_SET_ERR(EGL_BAD_SURFACE);
+ goto out;
+ }
+
+ if (!yagl_egl_context_uses_surface(egl_api_ts->context, surface)) {
+ YAGL_LOG_ERROR("Surface not attached to current context");
+ YAGL_SET_ERR(EGL_BAD_SURFACE);
+ goto out;
+ }
+
+ if (!egl_api_ts->context->client_ctx->read_pixels(egl_api_ts->context->client_ctx,
+ surface->width,
+ surface->height,
+ surface->bpp,
+ surface->host_pixels)) {
+ YAGL_LOG_ERROR("read_pixels failed");
+ YAGL_SET_ERR(EGL_BAD_SURFACE);
+ goto out;
+ }
+
+ yagl_egl_surface_lock(surface);
+
+ if (surface->bimage_ct) {
+ yagl_compiled_transfer_exec(surface->bimage_ct, surface->host_pixels);
+
+ ret = EGL_TRUE;
+ } else {
+ YAGL_LOG_ERROR("surface was destroyed, weird scenario!");
+ YAGL_SET_ERR(EGL_BAD_SURFACE);
+ }
+
+ yagl_egl_surface_unlock(surface);
+
+out:
+ yagl_egl_surface_release(surface);
+
+ return ret;
}
yagl_host_handle yagl_host_eglCreateWindowSurfaceOffscreenYAGL(yagl_host_handle dpy_,
target_ulong /* void* */ pixels_,
target_ulong /* const EGLint* */ attrib_list_)
{
- YAGL_UNIMPLEMENTED(eglCreatePbufferSurfaceOffscreenYAGL, 0);
+ yagl_host_handle ret = 0;
+ EGLint *attrib_list = NULL;
+ struct yagl_compiled_transfer *bimage_ct = NULL;
+ struct yagl_egl_pbuffer_attribs attribs;
+ struct yagl_egl_display *dpy = NULL;
+ struct yagl_egl_config *config = NULL;
+ struct yagl_egl_surface *surface = NULL;
+ int i = 0;
+
+ YAGL_LOG_FUNC_SET_TS(egl_api_ts->ts, eglCreatePbufferSurfaceOffscreenYAGL);
+
+ if (attrib_list_) {
+ attrib_list = yagl_mem_get_attrib_list(egl_api_ts->ts,
+ attrib_list_);
+
+ if (!attrib_list) {
+ YAGL_SET_ERR(EGL_BAD_ATTRIBUTE);
+ goto out;
+ }
+ }
+
+ bimage_ct = yagl_compiled_transfer_create(egl_api_ts->ts,
+ pixels_,
+ (width * height * bpp),
+ true);
+
+ if (!bimage_ct) {
+ YAGL_SET_ERR(EGL_BAD_ALLOC);
+ goto out;
+ }
+
+ yagl_egl_pbuffer_attribs_init(&attribs);
+
+ if (!yagl_egl_is_attrib_list_empty(attrib_list)) {
+ while (attrib_list[i] != EGL_NONE) {
+ switch (attrib_list[i]) {
+ case EGL_LARGEST_PBUFFER:
+ attribs.largest = (attrib_list[i + 1] ? EGL_TRUE : EGL_FALSE);
+ break;
+ case EGL_MIPMAP_TEXTURE:
+ attribs.tex_mipmap = (attrib_list[i + 1] ? EGL_TRUE : EGL_FALSE);
+ break;
+ case EGL_TEXTURE_FORMAT:
+ switch (attrib_list[i + 1]) {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_RGB:
+ case EGL_TEXTURE_RGBA:
+ attribs.tex_format = attrib_list[i + 1];
+ break;
+ default:
+ YAGL_SET_ERR(EGL_BAD_ATTRIBUTE);
+ goto out;
+ }
+ break;
+ case EGL_TEXTURE_TARGET:
+ switch (attrib_list[i + 1]) {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_2D:
+ attribs.tex_target = attrib_list[i + 1];
+ break;
+ default:
+ YAGL_SET_ERR(EGL_BAD_ATTRIBUTE);
+ goto out;
+ }
+ break;
+ case EGL_HEIGHT:
+ case EGL_WIDTH:
+ break;
+ default:
+ YAGL_SET_ERR(EGL_BAD_ATTRIBUTE);
+ goto out;
+ }
+
+ i += 2;
+ }
+ }
+
+ if (!yagl_validate_display(dpy_, &dpy)) {
+ goto out;
+ }
+
+ if (!yagl_validate_config(dpy, config_, &config)) {
+ goto out;
+ }
+
+ surface = yagl_egl_surface_create_pbuffer(dpy,
+ config,
+ &attribs,
+ bimage_ct,
+ width,
+ height,
+ bpp);
+
+ if (!surface) {
+ YAGL_SET_ERR(EGL_BAD_ALLOC);
+ goto out;
+ }
+
+ /*
+ * Owned by 'surface' now.
+ */
+ bimage_ct = NULL;
+
+ yagl_egl_display_add_surface(dpy, surface);
+ yagl_egl_surface_release(surface);
+
+ ret = surface->res.handle;
+
+out:
+ yagl_egl_config_release(config);
+ if (bimage_ct) {
+ yagl_compiled_transfer_destroy(bimage_ct);
+ }
+ g_free(attrib_list);
+
+ return ret;
}
yagl_host_handle yagl_host_eglCreatePixmapSurfaceOffscreenYAGL(yagl_host_handle dpy_,
yagl_host_handle yagl_host_eglGetCurrentContext(void);
yagl_host_handle yagl_host_eglGetCurrentSurface(EGLint readdraw);
yagl_host_handle yagl_host_eglGetCurrentDisplay(void);
-EGLBoolean yagl_host_eglQueryContext(yagl_host_handle dpy,
- yagl_host_handle ctx,
+EGLBoolean yagl_host_eglQueryContext(yagl_host_handle dpy_,
+ yagl_host_handle ctx_,
EGLint attribute,
- target_ulong /* EGLint* */ value);
+ target_ulong /* EGLint* */ value_);
EGLBoolean yagl_host_eglWaitGL(void);
EGLBoolean yagl_host_eglWaitNative(EGLint engine);
EGLBoolean yagl_host_eglSwapBuffers(yagl_host_handle dpy_,
yagl_host_handle surface_);
-EGLBoolean yagl_host_eglCopyBuffers(yagl_host_handle dpy,
- yagl_host_handle surface,
+EGLBoolean yagl_host_eglCopyBuffers(yagl_host_handle dpy_,
+ yagl_host_handle surface_,
EGLNativePixmapType target);
yagl_host_handle yagl_host_eglCreateWindowSurfaceOffscreenYAGL(yagl_host_handle dpy_,
yagl_host_handle config_,
return true;
}
+
+bool yagl_gles_buffer_get_parameter(struct yagl_gles_buffer *buffer,
+ GLenum pname,
+ GLint *param)
+{
+ qemu_mutex_lock(&buffer->mutex);
+
+ switch (pname) {
+ case GL_BUFFER_SIZE:
+ *param = buffer->size;
+ break;
+ case GL_BUFFER_USAGE:
+ *param = buffer->usage;
+ break;
+ default:
+ qemu_mutex_unlock(&buffer->mutex);
+ return false;
+ }
+
+ qemu_mutex_unlock(&buffer->mutex);
+
+ return true;
+}
+
+void yagl_gles_buffer_set_bound(struct yagl_gles_buffer *buffer)
+{
+ qemu_mutex_lock(&buffer->mutex);
+
+ buffer->was_bound = true;
+
+ qemu_mutex_unlock(&buffer->mutex);
+}
+
+bool yagl_gles_buffer_was_bound(struct yagl_gles_buffer *buffer)
+{
+ bool ret = false;
+
+ qemu_mutex_lock(&buffer->mutex);
+
+ ret = buffer->was_bound;
+
+ qemu_mutex_unlock(&buffer->mutex);
+
+ return ret;
+}
GLint size;
void *data;
GLenum usage;
+
+ bool was_bound;
};
struct yagl_gles_buffer
GLenum type,
GLenum target);
+bool yagl_gles_buffer_get_parameter(struct yagl_gles_buffer *buffer,
+ GLenum pname,
+ GLint *param);
+
+void yagl_gles_buffer_set_bound(struct yagl_gles_buffer *buffer);
+
+bool yagl_gles_buffer_was_bound(struct yagl_gles_buffer *buffer);
+
#endif
yagl_object_name texture_local_name)
{
yagl_gles_framebuffer_attachment framebuffer_attachment;
+ GLenum squashed_textarget;
if (!yagl_gles_validate_framebuffer_attachment(attachment,
&framebuffer_attachment)) {
return false;
}
- if (texture && (yagl_gles_texture_get_target(texture) != textarget)) {
+ if (!yagl_gles_validate_texture_target_squash(textarget,
+ &squashed_textarget)) {
+ return false;
+ }
+
+ if (texture && (yagl_gles_texture_get_target(texture) != squashed_textarget)) {
return false;
}
return true;
}
+
+bool yagl_gles_framebuffer_get_attachment_parameter(struct yagl_gles_framebuffer *fb,
+ GLenum attachment,
+ GLenum pname,
+ GLint *value)
+{
+ yagl_gles_framebuffer_attachment framebuffer_attachment;
+
+ if (!yagl_gles_validate_framebuffer_attachment(attachment,
+ &framebuffer_attachment)) {
+ return false;
+ }
+
+ qemu_mutex_lock(&fb->mutex);
+
+ switch (pname) {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ *value = fb->attachment_states[framebuffer_attachment].type;
+ break;
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ *value = fb->attachment_states[framebuffer_attachment].local_name;
+ break;
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ fb->driver_ps->GetFramebufferAttachmentParameteriv(fb->driver_ps,
+ fb->global_name,
+ attachment,
+ pname,
+ value);
+ break;
+ default:
+ qemu_mutex_unlock(&fb->mutex);
+ return false;
+ }
+
+ qemu_mutex_unlock(&fb->mutex);
+
+ return true;
+}
+
+void yagl_gles_framebuffer_set_bound(struct yagl_gles_framebuffer *fb)
+{
+ qemu_mutex_lock(&fb->mutex);
+
+ fb->was_bound = true;
+
+ qemu_mutex_unlock(&fb->mutex);
+}
+
+bool yagl_gles_framebuffer_was_bound(struct yagl_gles_framebuffer *fb)
+{
+ bool ret = false;
+
+ qemu_mutex_lock(&fb->mutex);
+
+ ret = fb->was_bound;
+
+ qemu_mutex_unlock(&fb->mutex);
+
+ return ret;
+}
QemuMutex mutex;
struct yagl_gles_framebuffer_attachment_state attachment_states[YAGL_NUM_GLES_FRAMEBUFFER_ATTACHMENTS];
+
+ bool was_bound;
};
struct yagl_gles_framebuffer
struct yagl_gles_texture *texture,
yagl_object_name texture_local_name);
+bool yagl_gles_framebuffer_get_attachment_parameter(struct yagl_gles_framebuffer *fb,
+ GLenum attachment,
+ GLenum pname,
+ GLint *value);
+
+void yagl_gles_framebuffer_set_bound(struct yagl_gles_framebuffer *fb);
+
+bool yagl_gles_framebuffer_was_bound(struct yagl_gles_framebuffer *fb);
+
#endif
rb->driver_ps->DeleteRenderbuffers(rb->driver_ps, 1, &rb->global_name);
}
+ qemu_mutex_destroy(&rb->mutex);
+
yagl_object_cleanup(&rb->base);
g_free(rb);
rb->driver_ps = driver_ps;
rb->global_name = global_name;
+ qemu_mutex_init(&rb->mutex);
+
return rb;
}
yagl_object_release(&rb->base);
}
}
+
+void yagl_gles_renderbuffer_set_bound(struct yagl_gles_renderbuffer *rb)
+{
+ qemu_mutex_lock(&rb->mutex);
+
+ rb->was_bound = true;
+
+ qemu_mutex_unlock(&rb->mutex);
+}
+
+bool yagl_gles_renderbuffer_was_bound(struct yagl_gles_renderbuffer *rb)
+{
+ bool ret = false;
+
+ qemu_mutex_lock(&rb->mutex);
+
+ ret = rb->was_bound;
+
+ qemu_mutex_unlock(&rb->mutex);
+
+ return ret;
+}
struct yagl_gles_driver_ps *driver_ps;
yagl_object_name global_name;
+
+ QemuMutex mutex;
+
+ bool was_bound;
};
struct yagl_gles_renderbuffer
*/
void yagl_gles_renderbuffer_release(struct yagl_gles_renderbuffer *rb);
+void yagl_gles_renderbuffer_set_bound(struct yagl_gles_renderbuffer *rb);
+
+bool yagl_gles_renderbuffer_was_bound(struct yagl_gles_renderbuffer *rb);
+
#endif
return true;
}
+
+bool yagl_gles_validate_texture_target_squash(GLenum target,
+ GLenum *squashed_target)
+{
+ switch (target) {
+ case GL_TEXTURE_2D:
+ *squashed_target = GL_TEXTURE_2D;
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ *squashed_target = GL_TEXTURE_CUBE_MAP;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
bool yagl_gles_validate_framebuffer_attachment(GLenum attachment,
yagl_gles_framebuffer_attachment *framebuffer_attachment);
+bool yagl_gles_validate_texture_target_squash(GLenum target,
+ GLenum *squashed_target);
+
#endif
goto out;
}
+ if (buffer_obj) {
+ yagl_gles_buffer_set_bound(buffer_obj);
+ }
+
out:
yagl_gles_buffer_release(buffer_obj);
}
void yagl_host_glGetBufferParameteriv(GLenum target,
GLenum pname,
- target_ulong /* GLint* */ params)
+ target_ulong /* GLint* */ params_)
{
- YAGL_UNIMPLEMENTED(glGetBufferParameteriv);
+ struct yagl_gles_buffer *buffer_obj = NULL;
+ GLint param = 0;
+
+ YAGL_GET_CTX(glGetBufferParameteriv);
+
+ if (!yagl_gles_is_buffer_target_valid(target)) {
+ YAGL_SET_ERR(GL_INVALID_ENUM);
+ goto out;
+ }
+
+ buffer_obj = yagl_gles_context_acquire_binded_buffer(ctx, target);
+
+ if (!buffer_obj) {
+ YAGL_SET_ERR(GL_INVALID_OPERATION);
+ goto out;
+ }
+
+ if (!yagl_gles_buffer_get_parameter(buffer_obj,
+ pname,
+ ¶m)) {
+ YAGL_SET_ERR(GL_INVALID_ENUM);
+ goto out;
+ }
+
+ if (params_) {
+ yagl_mem_put_GLint(ts, params_, param);
+ }
+
+out:
+ yagl_gles_buffer_release(buffer_obj);
}
GLenum yagl_host_glGetError(void)
void yagl_host_glGetTexParameterfv(GLenum target,
GLenum pname,
- target_ulong /* GLfloat* */ params)
+ target_ulong /* GLfloat* */ params_)
{
- YAGL_UNIMPLEMENTED(glGetTexParameterfv);
+ GLfloat params[10];
+
+ YAGL_GET_CTX(glGetTexParameterfv);
+
+ ctx->driver_ps->GetTexParameterfv(ctx->driver_ps,
+ target,
+ pname,
+ params);
+
+ if (params_) {
+ yagl_mem_put_GLfloat(ts, params_, params[0]);
+ }
}
void yagl_host_glGetTexParameteriv(GLenum target,
GLenum pname,
- target_ulong /* GLint* */ params)
+ target_ulong /* GLint* */ params_)
{
- YAGL_UNIMPLEMENTED(glGetTexParameteriv);
+ GLint params[10];
+
+ YAGL_GET_CTX(glGetTexParameteriv);
+
+ ctx->driver_ps->GetTexParameteriv(ctx->driver_ps,
+ target,
+ pname,
+ params);
+
+ if (params_) {
+ yagl_mem_put_GLint(ts, params_, params[0]);
+ }
}
void yagl_host_glHint(GLenum target,
GLboolean yagl_host_glIsBuffer(GLuint buffer)
{
- YAGL_UNIMPLEMENTED_RET(glIsBuffer, GL_FALSE);
+ struct yagl_gles_buffer *buffer_obj = NULL;
+ GLboolean ret = GL_FALSE;
+
+ YAGL_GET_CTX_RET(glIsBuffer, GL_FALSE);
+
+ buffer_obj = (struct yagl_gles_buffer*)yagl_sharegroup_acquire_object(ctx->base.sg,
+ YAGL_NS_BUFFER, buffer);
+
+ if (buffer_obj && yagl_gles_buffer_was_bound(buffer_obj)) {
+ ret = GL_TRUE;
+ }
+
+ yagl_gles_buffer_release(buffer_obj);
+
+ return ret;
}
GLboolean yagl_host_glIsEnabled(GLenum cap)
GLboolean yagl_host_glIsTexture(GLuint texture)
{
- YAGL_UNIMPLEMENTED_RET(glIsTexture, GL_FALSE);
+ struct yagl_gles_texture *texture_obj = NULL;
+ GLboolean ret = GL_FALSE;
+
+ YAGL_GET_CTX_RET(glIsTexture, GL_FALSE);
+
+ texture_obj = (struct yagl_gles_texture*)yagl_sharegroup_acquire_object(ctx->base.sg,
+ YAGL_NS_TEXTURE, texture);
+
+ if (texture_obj && (yagl_gles_texture_get_target(texture_obj) != 0)) {
+ ret = GL_TRUE;
+ }
+
+ yagl_gles_texture_release(texture_obj);
+
+ return ret;
}
void yagl_host_glLineWidth(GLfloat width)
void yagl_host_glTexParameterfv(GLenum target,
GLenum pname,
- target_ulong /* const GLfloat* */ params)
+ target_ulong /* const GLfloat* */ params_)
{
- YAGL_UNIMPLEMENTED(glTexParameterfv);
+ GLfloat params[10];
+
+ YAGL_GET_CTX(glTexParameterfv);
+
+ memset(params, 0, sizeof(params));
+
+ if (params_) {
+ if (!yagl_mem_get_GLfloat(ts, params_, params)) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+ }
+
+ ctx->driver_ps->TexParameterfv(ctx->driver_ps,
+ target,
+ pname,
+ (params_ ? params : NULL));
+
+out:
+ (void)0;
}
void yagl_host_glTexParameteri(GLenum target,
void yagl_host_glTexParameteriv(GLenum target,
GLenum pname,
- target_ulong /* const GLint* */ params)
+ target_ulong /* const GLint* */ params_)
{
- YAGL_UNIMPLEMENTED(glTexParameteriv);
+ GLint params[10];
+
+ YAGL_GET_CTX(glTexParameteriv);
+
+ memset(params, 0, sizeof(params));
+
+ if (params_) {
+ if (!yagl_mem_get_GLint(ts, params_, params)) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+ }
+
+ ctx->driver_ps->TexParameteriv(ctx->driver_ps,
+ target,
+ pname,
+ (params_ ? params : NULL));
+
+out:
+ (void)0;
}
void yagl_host_glTexSubImage2D(GLenum target,
return str_len + 1;
}
+
+void yagl_host_glEGLImageTargetTexture2DYAGL(GLenum target,
+ uint32_t width,
+ uint32_t height,
+ uint32_t bpp,
+ target_ulong /* const void* */ pixels_)
+{
+ void *pixels = NULL;
+ GLenum format = 0;
+ GLsizei unpack_alignment = 0;
+
+ YAGL_GET_CTX(glEGLImageTargetTexture2DYAGL);
+
+ if (pixels_ && (width > 0) && (height > 0) && (bpp > 0)) {
+ pixels = yagl_gles_context_malloc(ctx, width * height * bpp);
+ if (!yagl_mem_get(ts,
+ pixels_,
+ width * height * bpp,
+ pixels)) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+ }
+
+ switch (bpp) {
+ case 3:
+ format = GL_RGB;
+ break;
+ case 4:
+ format = GL_BGRA;
+ break;
+ default:
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ ctx->driver_ps->GetIntegerv(ctx->driver_ps,
+ GL_UNPACK_ALIGNMENT,
+ &unpack_alignment);
+
+ ctx->driver_ps->PixelStorei(ctx->driver_ps,
+ GL_UNPACK_ALIGNMENT,
+ 1);
+
+ ctx->driver_ps->TexImage2D(ctx->driver_ps,
+ target,
+ 0,
+ GL_RGB,
+ width,
+ height,
+ 0,
+ format,
+ GL_UNSIGNED_BYTE,
+ pixels);
+
+ ctx->driver_ps->PixelStorei(ctx->driver_ps,
+ GL_UNPACK_ALIGNMENT,
+ unpack_alignment);
+
+out:
+ (void)0;
+}
target_ulong /* GLboolean* */ params_);
void yagl_host_glGetBufferParameteriv(GLenum target,
GLenum pname,
- target_ulong /* GLint* */ params);
+ target_ulong /* GLint* */ params_);
GLenum yagl_host_glGetError(void);
void yagl_host_glGetFloatv(GLenum pname,
target_ulong /* GLfloat* */ params_);
target_ulong /* GLint* */ params_);
void yagl_host_glGetTexParameterfv(GLenum target,
GLenum pname,
- target_ulong /* GLfloat* */ params);
+ target_ulong /* GLfloat* */ params_);
void yagl_host_glGetTexParameteriv(GLenum target,
GLenum pname,
- target_ulong /* GLint* */ params);
+ target_ulong /* GLint* */ params_);
void yagl_host_glHint(GLenum target,
GLenum mode);
GLboolean yagl_host_glIsBuffer(GLuint buffer);
GLfloat param);
void yagl_host_glTexParameterfv(GLenum target,
GLenum pname,
- target_ulong /* const GLfloat* */ params);
+ target_ulong /* const GLfloat* */ params_);
void yagl_host_glTexParameteri(GLenum target,
GLenum pname,
GLint param);
void yagl_host_glTexParameteriv(GLenum target,
GLenum pname,
- target_ulong /* const GLint* */ params);
+ target_ulong /* const GLint* */ params_);
void yagl_host_glTexSubImage2D(GLenum target,
GLint level,
GLint xoffset,
GLsizei width,
GLsizei height);
GLuint yagl_host_glGetExtensionStringYAGL(target_ulong /* GLchar* */ str_);
+void yagl_host_glEGLImageTargetTexture2DYAGL(GLenum target,
+ uint32_t width,
+ uint32_t height,
+ uint32_t bpp,
+ target_ulong /* const void* */ pixels_);
#endif
return out_buff;
}
-const uint32_t yagl_gles1_api_num_funcs = 144;
+/*
+ * glEGLImageTargetTexture2DYAGL dispatcher. id = 145
+ */
+static uint8_t* yagl_func_glEGLImageTargetTexture2DYAGL(struct yagl_thread_state *ts,
+ uint8_t *out_buff,
+ uint8_t *in_buff)
+{
+ GLenum target = yagl_marshal_get_GLenum(&out_buff);
+ uint32_t width = yagl_marshal_get_uint32_t(&out_buff);
+ uint32_t height = yagl_marshal_get_uint32_t(&out_buff);
+ uint32_t bpp = yagl_marshal_get_uint32_t(&out_buff);
+ target_ulong pixels = yagl_marshal_get_ptr(&out_buff);
+ YAGL_LOG_FUNC_ENTER_SPLIT5(ts->ps->id, ts->id, glEGLImageTargetTexture2DYAGL, GLenum, uint32_t, uint32_t, uint32_t, target_ulong, target, width, height, bpp, pixels);
+ yagl_host_glEGLImageTargetTexture2DYAGL(target, width, height, bpp, pixels);
+ YAGL_LOG_FUNC_EXIT(NULL);
+ return out_buff;
+}
+
+const uint32_t yagl_gles1_api_num_funcs = 145;
yagl_api_func yagl_gles1_api_funcs[] = {
&yagl_func_glAlphaFunc,
&yagl_func_glTranslatex,
&yagl_func_glVertexPointer,
&yagl_func_glViewport,
- &yagl_func_glGetExtensionStringYAGL
+ &yagl_func_glGetExtensionStringYAGL,
+ &yagl_func_glEGLImageTargetTexture2DYAGL
};
return out_buff;
}
-const uint32_t yagl_gles2_api_num_funcs = 142;
+/*
+ * glEGLImageTargetTexture2DYAGL dispatcher. id = 143
+ */
+static uint8_t* yagl_func_glEGLImageTargetTexture2DYAGL(struct yagl_thread_state *ts,
+ uint8_t *out_buff,
+ uint8_t *in_buff)
+{
+ GLenum target = yagl_marshal_get_GLenum(&out_buff);
+ uint32_t width = yagl_marshal_get_uint32_t(&out_buff);
+ uint32_t height = yagl_marshal_get_uint32_t(&out_buff);
+ uint32_t bpp = yagl_marshal_get_uint32_t(&out_buff);
+ target_ulong pixels = yagl_marshal_get_ptr(&out_buff);
+ YAGL_LOG_FUNC_ENTER_SPLIT5(ts->ps->id, ts->id, glEGLImageTargetTexture2DYAGL, GLenum, uint32_t, uint32_t, uint32_t, target_ulong, target, width, height, bpp, pixels);
+ yagl_host_glEGLImageTargetTexture2DYAGL(target, width, height, bpp, pixels);
+ YAGL_LOG_FUNC_EXIT(NULL);
+ return out_buff;
+}
+
+const uint32_t yagl_gles2_api_num_funcs = 143;
yagl_api_func yagl_gles2_api_funcs[] = {
&yagl_func_glActiveTexture,
&yagl_func_glVertexAttrib4fv,
&yagl_func_glVertexAttribPointer,
&yagl_func_glViewport,
- &yagl_func_glGetExtensionStringYAGL
+ &yagl_func_glGetExtensionStringYAGL,
+ &yagl_func_glEGLImageTargetTexture2DYAGL
};
struct yagl_gles2_context *gles2_ctx = (struct yagl_gles2_context*)ctx;
const GLchar *mandatory_extensions =
- "GL_OES_depth24 GL_OES_depth32 "
+ "GL_OES_EGL_image 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 ";
name);
}
+void yagl_gles2_program_get_info_log(struct yagl_gles2_program *program,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *infolog)
+{
+ program->driver_ps->GetProgramInfoLog(program->driver_ps,
+ program->global_name,
+ bufsize,
+ length,
+ infolog);
+}
+
+void yagl_gles2_program_validate(struct yagl_gles2_program *program)
+{
+ program->driver_ps->ValidateProgram(program->driver_ps,
+ program->global_name);
+}
+
void yagl_gles2_program_acquire(struct yagl_gles2_program *program)
{
if (program) {
GLenum *type,
GLchar *name);
+void yagl_gles2_program_get_info_log(struct yagl_gles2_program *program,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *infolog);
+
+void yagl_gles2_program_validate(struct yagl_gles2_program *program);
+
/*
* Passing NULL won't hurt, this is for convenience.
*/
param);
}
+void yagl_gles2_shader_get_source(struct yagl_gles2_shader *shader,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *source)
+{
+ shader->driver_ps->GetShaderSource(shader->driver_ps,
+ shader->global_name,
+ bufsize,
+ length,
+ source);
+}
+
+void yagl_gles2_shader_get_info_log(struct yagl_gles2_shader *shader,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *infolog)
+{
+ shader->driver_ps->GetShaderInfoLog(shader->driver_ps,
+ shader->global_name,
+ bufsize,
+ length,
+ infolog);
+}
+
void yagl_gles2_shader_acquire(struct yagl_gles2_shader *shader)
{
if (shader) {
GLenum pname,
GLint *param);
+void yagl_gles2_shader_get_source(struct yagl_gles2_shader *shader,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *source);
+
+void yagl_gles2_shader_get_info_log(struct yagl_gles2_shader *shader,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *infolog);
+
/*
* Passing NULL won't hurt, this is for convenience.
*/
YAGL_GET_CTX(func); \
YAGL_LOG_WARN("NOT IMPLEMENTED!!!");
+static bool yagl_get_array_param(struct yagl_gles_array *array,
+ GLenum pname,
+ GLint *param)
+{
+ switch (pname) {
+ case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+ *param = array->vbo_local_name;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+ *param = array->enabled;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+ *param = array->size;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+ *param = array->stride;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+ *param = array->type;
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+ *param = array->normalized;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
static struct yagl_client_context
*yagl_host_gles2_create_ctx(struct yagl_client_interface *iface,
struct yagl_sharegroup *sg)
target,
(framebuffer_obj ? framebuffer_obj->global_name : 0));
+ if (framebuffer_obj) {
+ yagl_gles_framebuffer_set_bound(framebuffer_obj);
+ }
+
out:
yagl_gles_framebuffer_release(framebuffer_obj);
}
target,
(renderbuffer_obj ? renderbuffer_obj->global_name : 0));
+ if (renderbuffer_obj) {
+ yagl_gles_renderbuffer_set_bound(renderbuffer_obj);
+ }
+
out:
yagl_gles_renderbuffer_release(renderbuffer_obj);
}
void yagl_host_glGetAttachedShaders(GLuint program,
GLsizei maxcount,
- target_ulong /* GLsizei* */ count,
- target_ulong /* GLuint* */ shaders)
+ target_ulong /* GLsizei* */ count_,
+ target_ulong /* GLuint* */ shaders_)
{
- YAGL_UNIMPLEMENTED(glGetAttachedShaders);
+ struct yagl_gles2_program *program_obj = NULL;
+ GLsizei count = 0;
+ GLuint *shaders = 0;
+
+ YAGL_GET_CTX(glGetAttachedShaders);
+
+ program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
+ YAGL_NS_PROGRAM, program);
+
+ if (!program_obj) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ if (maxcount < 0) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ if (maxcount > 0) {
+ shaders = yagl_gles_context_malloc0(&ctx->base,
+ maxcount * sizeof(*shaders));
+
+ if (program_obj->vertex_shader_local_name != 0) {
+ if (count < maxcount) {
+ shaders[count++] = program_obj->vertex_shader_local_name;
+ }
+ }
+
+ if (program_obj->fragment_shader_local_name != 0) {
+ if (count < maxcount) {
+ shaders[count++] = program_obj->fragment_shader_local_name;
+ }
+ }
+
+ yagl_mem_put(gles2_api_ts->ts,
+ shaders_,
+ count * sizeof(*shaders),
+ shaders);
+ }
+
+ if (count_) {
+ yagl_mem_put_GLsizei(gles2_api_ts->ts, count_, count);
+ }
+
+out:
+ yagl_gles2_program_release(program_obj);
}
int yagl_host_glGetAttribLocation(GLuint program,
void yagl_host_glGetFramebufferAttachmentParameteriv(GLenum target,
GLenum attachment,
GLenum pname,
- target_ulong /* GLint* */ params)
+ target_ulong /* GLint* */ params_)
{
- YAGL_UNIMPLEMENTED(glGetFramebufferAttachmentParameteriv);
+ struct yagl_gles_framebuffer *framebuffer_obj = NULL;
+ GLint param = 0;
+
+ YAGL_GET_CTX(glGetFramebufferAttachmentParameteriv);
+
+ framebuffer_obj = yagl_gles_context_acquire_binded_framebuffer(&ctx->base, target);
+
+ if (!framebuffer_obj) {
+ YAGL_SET_ERR(GL_INVALID_ENUM);
+ goto out;
+ }
+
+ if (!yagl_gles_framebuffer_get_attachment_parameter(framebuffer_obj,
+ attachment,
+ pname,
+ ¶m)) {
+ YAGL_SET_ERR(GL_INVALID_ENUM);
+ goto out;
+ }
+
+ if (params_) {
+ yagl_mem_put_GLint(gles2_api_ts->ts, params_, param);
+ }
+
+out:
+ yagl_gles_framebuffer_release(framebuffer_obj);
}
void yagl_host_glGetProgramiv(GLuint program,
void yagl_host_glGetProgramInfoLog(GLuint program,
GLsizei bufsize,
- target_ulong /* GLsizei* */ length,
- target_ulong /* GLchar* */ infolog)
+ target_ulong /* GLsizei* */ length_,
+ target_ulong /* GLchar* */ infolog_)
{
- YAGL_UNIMPLEMENTED(glGetProgramInfoLog);
+ struct yagl_gles2_program *program_obj = NULL;
+ GLsizei length = 0;
+ GLchar *infolog = NULL;
+
+ YAGL_GET_CTX(glGetProgramInfoLog);
+
+ program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
+ YAGL_NS_PROGRAM, program);
+
+ if (!program_obj) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ if (bufsize < 0) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ if (bufsize > 0) {
+ infolog = yagl_gles_context_malloc(&ctx->base, bufsize);
+ }
+
+ yagl_gles2_program_get_info_log(program_obj, bufsize, &length, infolog);
+
+ if (length_) {
+ yagl_mem_put_GLsizei(gles2_api_ts->ts, length_, length);
+ }
+
+ if (infolog_ && infolog) {
+ yagl_mem_put(gles2_api_ts->ts, infolog_, length + 1, infolog);
+ }
+
+out:
+ yagl_gles2_program_release(program_obj);
}
void yagl_host_glGetRenderbufferParameteriv(GLenum target,
GLenum pname,
- target_ulong /* GLint* */ params)
+ target_ulong /* GLint* */ params_)
{
- YAGL_UNIMPLEMENTED(glGetRenderbufferParameteriv);
+ GLint params[10];
+
+ YAGL_GET_CTX(glGetRenderbufferParameteriv);
+
+ ctx->driver_ps->common->GetRenderbufferParameteriv(ctx->driver_ps->common,
+ target,
+ pname,
+ params);
+
+ if (params_) {
+ yagl_mem_put_GLint(gles2_api_ts->ts, params_, params[0]);
+ }
}
void yagl_host_glGetShaderiv(GLuint shader,
void yagl_host_glGetShaderInfoLog(GLuint shader,
GLsizei bufsize,
- target_ulong /* GLsizei* */ length,
- target_ulong /* GLchar* */ infolog)
+ target_ulong /* GLsizei* */ length_,
+ target_ulong /* GLchar* */ infolog_)
{
- YAGL_UNIMPLEMENTED(glGetShaderInfoLog);
+ struct yagl_gles2_shader *shader_obj = NULL;
+ GLsizei length = 0;
+ GLchar *infolog = NULL;
+
+ YAGL_GET_CTX(glGetShaderInfoLog);
+
+ shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
+ YAGL_NS_SHADER, shader);
+
+ if (!shader_obj) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ if (bufsize < 0) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ if (bufsize > 0) {
+ infolog = yagl_gles_context_malloc(&ctx->base, bufsize);
+ }
+
+ yagl_gles2_shader_get_info_log(shader_obj, bufsize, &length, infolog);
+
+ if (length_) {
+ yagl_mem_put_GLsizei(gles2_api_ts->ts, length_, length);
+ }
+
+ if (infolog_ && infolog) {
+ yagl_mem_put(gles2_api_ts->ts, infolog_, length + 1, infolog);
+ }
+
+out:
+ yagl_gles2_shader_release(shader_obj);
}
void yagl_host_glGetShaderPrecisionFormat(GLenum shadertype,
GLenum precisiontype,
- target_ulong /* GLint* */ range,
- target_ulong /* GLint* */ precision)
+ target_ulong /* GLint* */ range_,
+ target_ulong /* GLint* */ precision_)
{
- YAGL_UNIMPLEMENTED(glGetShaderPrecisionFormat);
+ GLint range[2] = { 0, 0 };
+ GLint precision = 0;
+
+ YAGL_GET_CTX(glGetShaderPrecisionFormat);
+
+ switch (precisiontype) {
+ case GL_LOW_INT:
+ case GL_MEDIUM_INT:
+ case GL_HIGH_INT:
+ range[0] = range[1] = 16;
+ precision = 0;
+ break;
+ case GL_LOW_FLOAT:
+ case GL_MEDIUM_FLOAT:
+ case GL_HIGH_FLOAT:
+ range[0] = range[1] = 127;
+ precision = 24;
+ break;
+ default:
+ YAGL_SET_ERR(GL_INVALID_ENUM);
+ goto out;
+ }
+
+ if (range_) {
+ yagl_mem_put_GLint(gles2_api_ts->ts,
+ range_,
+ range[0]);
+ yagl_mem_put_GLint(gles2_api_ts->ts,
+ range_ + sizeof(range[0]),
+ range[1]);
+ }
+
+ if (precision_) {
+ yagl_mem_put_GLint(gles2_api_ts->ts, precision_, precision);
+ }
+
+out:
+ (void)0;
}
void yagl_host_glGetShaderSource(GLuint shader,
GLsizei bufsize,
- target_ulong /* GLsizei* */ length,
- target_ulong /* GLchar* */ source)
+ target_ulong /* GLsizei* */ length_,
+ target_ulong /* GLchar* */ source_)
{
- YAGL_UNIMPLEMENTED(glGetShaderSource);
+ struct yagl_gles2_shader *shader_obj = NULL;
+ GLsizei length = 0;
+ GLchar *source = NULL;
+
+ YAGL_GET_CTX(glGetShaderSource);
+
+ shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
+ YAGL_NS_SHADER, shader);
+
+ if (!shader_obj) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ if (bufsize < 0) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ if (bufsize > 0) {
+ source = yagl_gles_context_malloc(&ctx->base, bufsize);
+ }
+
+ yagl_gles2_shader_get_source(shader_obj, bufsize, &length, source);
+
+ if (length_) {
+ yagl_mem_put_GLsizei(gles2_api_ts->ts, length_, length);
+ }
+
+ if (source_ && source) {
+ yagl_mem_put(gles2_api_ts->ts, source_, length + 1, source);
+ }
+
+out:
+ yagl_gles2_shader_release(shader_obj);
}
void yagl_host_glGetUniformfv(GLuint program,
GLint location,
target_ulong /* GLfloat* */ params)
{
+ /*
+ * Currently I don't see how to implement this nicely...
+ */
+
YAGL_UNIMPLEMENTED(glGetUniformfv);
+ YAGL_SET_ERR(GL_INVALID_OPERATION);
}
void yagl_host_glGetUniformiv(GLuint program,
GLint location,
target_ulong /* GLint* */ params)
{
+ /*
+ * Currently I don't see how to implement this nicely...
+ */
+
YAGL_UNIMPLEMENTED(glGetUniformiv);
+ YAGL_SET_ERR(GL_INVALID_OPERATION);
}
int yagl_host_glGetUniformLocation(GLuint program,
void yagl_host_glGetVertexAttribfv(GLuint index,
GLenum pname,
- target_ulong /* GLfloat* */ params)
+ target_ulong /* GLfloat* */ params_)
{
- YAGL_UNIMPLEMENTED(glGetVertexAttribfv);
+ struct yagl_gles_array *array = NULL;
+ int i, count = 0;
+ GLfloat *params = NULL;
+ GLint param = 0;
+
+ YAGL_GET_CTX(glGetVertexAttribfv);
+
+ array = yagl_gles_context_get_array(&ctx->base, index);
+
+ if (!array) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ if (!yagl_gles2_get_array_param_count(pname, &count)) {
+ YAGL_SET_ERR(GL_INVALID_ENUM);
+ goto out;
+ }
+
+ params = yagl_gles_context_malloc0(&ctx->base, count * sizeof(*params));
+
+ if (yagl_get_array_param(array, pname, ¶m)) {
+ params[0] = param;
+ } else {
+ ctx->driver_ps->GetVertexAttribfv(ctx->driver_ps, index, pname, params);
+ }
+
+ if (params_) {
+ for (i = 0; i < count; ++i) {
+ yagl_mem_put_GLfloat(gles2_api_ts->ts,
+ params_ + (i * sizeof(*params)),
+ params[i]);
+ }
+ }
+
+out:
+ (void)0;
}
void yagl_host_glGetVertexAttribiv(GLuint index,
params = yagl_gles_context_malloc0(&ctx->base, count * sizeof(*params));
- switch (pname) {
- case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- params[0] = array->vbo_local_name;
- break;
- case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
- params[0] = array->enabled;
- break;
- case GL_VERTEX_ATTRIB_ARRAY_SIZE:
- params[0] = array->size;
- break;
- case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
- params[0] = array->stride;
- break;
- case GL_VERTEX_ATTRIB_ARRAY_TYPE:
- params[0] = array->type;
- break;
- case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
- params[0] = array->normalized;
- break;
- default:
+ if (!yagl_get_array_param(array, pname, params)) {
ctx->driver_ps->GetVertexAttribiv(ctx->driver_ps, index, pname, params);
- break;
}
if (params_) {
void yagl_host_glGetVertexAttribPointerv(GLuint index,
GLenum pname,
- target_ulong /* GLvoid** */ pointer)
+ target_ulong /* GLvoid** */ pointer_)
{
- YAGL_UNIMPLEMENTED(glGetVertexAttribPointerv);
+ struct yagl_gles_array *array = NULL;
+ target_ulong pointer = 0;
+
+ YAGL_GET_CTX(glGetVertexAttribPointerv);
+
+ array = yagl_gles_context_get_array(&ctx->base, index);
+
+ if (!array) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ if (array->vbo) {
+ pointer = array->offset;
+ } else {
+ pointer = array->target_data;
+ }
+
+ if (pointer_) {
+ yagl_mem_put_ptr(gles2_api_ts->ts, pointer_, pointer);
+ }
+
+out:
+ (void)0;
}
GLboolean yagl_host_glIsFramebuffer(GLuint framebuffer)
{
- YAGL_UNIMPLEMENTED_RET(glIsFramebuffer, GL_FALSE);
+ struct yagl_gles_framebuffer *framebuffer_obj = NULL;
+ GLboolean ret = GL_FALSE;
+
+ YAGL_GET_CTX_RET(glIsFramebuffer, GL_FALSE);
+
+ framebuffer_obj = (struct yagl_gles_framebuffer*)yagl_sharegroup_acquire_object(ctx->sg,
+ YAGL_NS_FRAMEBUFFER, framebuffer);
+
+ if (framebuffer_obj && yagl_gles_framebuffer_was_bound(framebuffer_obj)) {
+ ret = GL_TRUE;
+ }
+
+ yagl_gles_framebuffer_release(framebuffer_obj);
+
+ return ret;
}
GLboolean yagl_host_glIsProgram(GLuint program)
{
- YAGL_UNIMPLEMENTED_RET(glIsProgram, GL_FALSE);
+ struct yagl_gles2_program *program_obj = NULL;
+ GLboolean ret = GL_FALSE;
+
+ YAGL_GET_CTX_RET(glIsProgram, GL_FALSE);
+
+ program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
+ YAGL_NS_PROGRAM, program);
+
+ if (program_obj) {
+ ret = GL_TRUE;
+ }
+
+ yagl_gles2_program_release(program_obj);
+
+ return ret;
}
GLboolean yagl_host_glIsRenderbuffer(GLuint renderbuffer)
{
- YAGL_UNIMPLEMENTED_RET(glIsRenderbuffer, GL_FALSE);
+ struct yagl_gles_renderbuffer *renderbuffer_obj = NULL;
+ GLboolean ret = GL_FALSE;
+
+ YAGL_GET_CTX_RET(glIsRenderbuffer, GL_FALSE);
+
+ renderbuffer_obj = (struct yagl_gles_renderbuffer*)yagl_sharegroup_acquire_object(ctx->sg,
+ YAGL_NS_RENDERBUFFER, renderbuffer);
+
+ if (renderbuffer_obj && yagl_gles_renderbuffer_was_bound(renderbuffer_obj)) {
+ ret = GL_TRUE;
+ }
+
+ yagl_gles_renderbuffer_release(renderbuffer_obj);
+
+ return ret;
}
GLboolean yagl_host_glIsShader(GLuint shader)
{
- YAGL_UNIMPLEMENTED_RET(glIsShader, GL_FALSE);
+ struct yagl_gles2_shader *shader_obj = NULL;
+ GLboolean ret = GL_FALSE;
+
+ YAGL_GET_CTX_RET(glIsShader, GL_FALSE);
+
+ shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
+ YAGL_NS_SHADER, shader);
+
+ if (shader_obj) {
+ ret = GL_TRUE;
+ }
+
+ yagl_gles2_shader_release(shader_obj);
+
+ return ret;
}
void yagl_host_glLinkProgram(GLuint program)
target_ulong /* const GLvoid* */ binary,
GLsizei length)
{
+ /*
+ * Don't allow to load precompiled shaders.
+ */
+
YAGL_UNIMPLEMENTED(glShaderBinary);
+ YAGL_SET_ERR(GL_INVALID_OPERATION);
}
void yagl_host_glShaderSource(GLuint shader,
void yagl_host_glValidateProgram(GLuint program)
{
- YAGL_UNIMPLEMENTED(glValidateProgram);
+ struct yagl_gles2_program *program_obj = NULL;
+
+ YAGL_GET_CTX(glValidateProgram);
+
+ program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
+ YAGL_NS_PROGRAM, program);
+
+ if (!program_obj) {
+ YAGL_SET_ERR(GL_INVALID_VALUE);
+ goto out;
+ }
+
+ yagl_gles2_program_validate(program_obj);
+
+out:
+ yagl_gles2_program_release(program_obj);
}
void yagl_host_glVertexAttrib1f(GLuint indx,
target_ulong /* GLchar* */ name_);
void yagl_host_glGetAttachedShaders(GLuint program,
GLsizei maxcount,
- target_ulong /* GLsizei* */ count,
- target_ulong /* GLuint* */ shaders);
+ target_ulong /* GLsizei* */ count_,
+ target_ulong /* GLuint* */ shaders_);
int yagl_host_glGetAttribLocation(GLuint program,
target_ulong /* const GLchar* */ name_);
void yagl_host_glGetFramebufferAttachmentParameteriv(GLenum target,
GLenum attachment,
GLenum pname,
- target_ulong /* GLint* */ params);
+ target_ulong /* GLint* */ params_);
void yagl_host_glGetProgramiv(GLuint program,
GLenum pname,
target_ulong /* GLint* */ params_);
void yagl_host_glGetProgramInfoLog(GLuint program,
GLsizei bufsize,
- target_ulong /* GLsizei* */ length,
- target_ulong /* GLchar* */ infolog);
+ target_ulong /* GLsizei* */ length_,
+ target_ulong /* GLchar* */ infolog_);
void yagl_host_glGetRenderbufferParameteriv(GLenum target,
GLenum pname,
- target_ulong /* GLint* */ params);
+ target_ulong /* GLint* */ params_);
void yagl_host_glGetShaderiv(GLuint shader,
GLenum pname,
target_ulong /* GLint* */ params_);
void yagl_host_glGetShaderInfoLog(GLuint shader,
GLsizei bufsize,
- target_ulong /* GLsizei* */ length,
- target_ulong /* GLchar* */ infolog);
+ target_ulong /* GLsizei* */ length_,
+ target_ulong /* GLchar* */ infolog_);
void yagl_host_glGetShaderPrecisionFormat(GLenum shadertype,
GLenum precisiontype,
- target_ulong /* GLint* */ range,
- target_ulong /* GLint* */ precision);
+ target_ulong /* GLint* */ range_,
+ target_ulong /* GLint* */ precision_);
void yagl_host_glGetShaderSource(GLuint shader,
GLsizei bufsize,
- target_ulong /* GLsizei* */ length,
- target_ulong /* GLchar* */ source);
+ target_ulong /* GLsizei* */ length_,
+ target_ulong /* GLchar* */ source_);
void yagl_host_glGetUniformfv(GLuint program,
GLint location,
target_ulong /* GLfloat* */ params);
target_ulong /* const GLchar* */ name_);
void yagl_host_glGetVertexAttribfv(GLuint index,
GLenum pname,
- target_ulong /* GLfloat* */ params);
+ target_ulong /* GLfloat* */ params_);
void yagl_host_glGetVertexAttribiv(GLuint index,
GLenum pname,
target_ulong /* GLint* */ params_);
void yagl_host_glGetVertexAttribPointerv(GLuint index,
GLenum pname,
- target_ulong /* GLvoid** */ pointer);
+ target_ulong /* GLvoid** */ pointer_);
GLboolean yagl_host_glIsFramebuffer(GLuint framebuffer);
GLboolean yagl_host_glIsProgram(GLuint program);
GLboolean yagl_host_glIsRenderbuffer(GLuint renderbuffer);
int glx_attribs[] = {
GLX_PBUFFER_WIDTH, width,
GLX_PBUFFER_HEIGHT, height,
- GLX_LARGEST_PBUFFER, (attribs->largest ? True : False),
+ GLX_LARGEST_PBUFFER, False,
GLX_PRESERVED_CONTENTS, True,
None
};
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_PROC4(glGetFramebufferAttachmentParameterivEXT, GLenum, GLenum, GLenum, GLint*, target, attachment, pname, params);
+ YAGL_GLES_OGL_PROC3(glGetRenderbufferParameterivEXT, GLenum, GLenum, GLint*, target, pname, params);
};
YAGL_GLES_OGL_PROC_IMPL1(yagl_gles_driver_ps, yagl_gles_ogl_ps, yagl_gles_ogl, ActiveTexture, GLenum, texture)
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)
+YAGL_GLES_OGL_PROC_IMPL4(yagl_gles_driver_ps, yagl_gles_ogl_ps, yagl_gles_ogl, GetFramebufferAttachmentParameterivEXT, GLenum, GLenum, GLenum, GLint*, target, attachment, pname, params);
+YAGL_GLES_OGL_PROC_IMPL3(yagl_gles_driver_ps, yagl_gles_ogl_ps, yagl_gles_ogl, GetRenderbufferParameterivEXT, GLenum, GLenum, GLint*, target, pname, params);
struct yagl_gles_ogl_ps
*yagl_gles_ogl_ps_create(struct yagl_gles_ogl *gles_ogl,
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);
+ gles_ogl_ps->base.GetFramebufferAttachmentParameteriv = &yagl_gles_ogl_GetFramebufferAttachmentParameterivEXT;
+ gles_ogl_ps->base.GetRenderbufferParameteriv = &yagl_gles_ogl_GetRenderbufferParameterivEXT;
YAGL_LOG_FUNC_EXIT(NULL);
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_GLES_OGL_GET_PROC(gles_ogl, glGetFramebufferAttachmentParameterivEXT);
+ YAGL_GLES_OGL_GET_PROC(gles_ogl, glGetRenderbufferParameterivEXT);
YAGL_LOG_FUNC_EXIT(NULL);
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)
+ YAGL_GLES_DRIVER_FUNC4(struct yagl_gles_driver_ps *driver_ps, GetFramebufferAttachmentParameteriv, GLenum, GLenum, GLenum, GLint*, target, attachment, pname, params);
+ YAGL_GLES_DRIVER_FUNC3(struct yagl_gles_driver_ps *driver_ps, GetRenderbufferParameteriv, GLenum, GLenum, GLint*, target, pname, params);
};
void yagl_gles_driver_ps_init(struct yagl_gles_driver_ps *driver_ps,
#define yagl_mem_put_host_handle(ts, va, value) yagl_mem_put_uint32((ts), (va), (value))
#define yagl_mem_get_host_handle(ts, va, value) yagl_mem_get_uint32((ts), (va), (value))
+#if TARGET_LONG_SIZE == 4
+#define yagl_mem_put_ptr(ts, va, value) yagl_mem_put_uint32((ts), (va), (value))
+#else
+#error 64-bit ptr not supported
+#endif
+
#endif
/*
* Whenever protocol changes be sure to bump this.
*/
-#define YAGL_VERSION 8
+#define YAGL_VERSION 9
#endif