From: Stanislav Vorobiov Date: Mon, 24 Sep 2012 15:00:44 +0000 (+0400) Subject: YaGL: Fixed a SEGV in eglChooseConfig X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~1405^2~20 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2553c6faa683772e946982b096503ae9c2431b73;p=sdk%2Femulator%2Fqemu.git YaGL: Fixed a SEGV in eglChooseConfig 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 --- diff --git a/hw/yagl_apis/egl/yagl_egl_calls.c b/hw/yagl_apis/egl/yagl_egl_calls.c index 0427d1d673..b51688a247 100644 --- a/hw/yagl_apis/egl/yagl_egl_calls.c +++ b/hw/yagl_apis/egl/yagl_egl_calls.c @@ -174,21 +174,7 @@ static uint8_t* yagl_func_eglBindAPI(struct yagl_thread_state *ts, } /* - * 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, @@ -202,7 +188,7 @@ static uint8_t* yagl_func_eglWaitClient(struct yagl_thread_state *ts, } /* - * eglReleaseThread dispatcher. id = 13 + * eglReleaseThread dispatcher. id = 12 */ static uint8_t* yagl_func_eglReleaseThread(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -216,7 +202,7 @@ static uint8_t* yagl_func_eglReleaseThread(struct yagl_thread_state *ts, } /* - * eglCreatePbufferFromClientBuffer dispatcher. id = 14 + * eglCreatePbufferFromClientBuffer dispatcher. id = 13 */ static uint8_t* yagl_func_eglCreatePbufferFromClientBuffer(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -235,7 +221,7 @@ static uint8_t* yagl_func_eglCreatePbufferFromClientBuffer(struct yagl_thread_st } /* - * eglSurfaceAttrib dispatcher. id = 15 + * eglSurfaceAttrib dispatcher. id = 14 */ static uint8_t* yagl_func_eglSurfaceAttrib(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -253,7 +239,7 @@ static uint8_t* yagl_func_eglSurfaceAttrib(struct yagl_thread_state *ts, } /* - * eglBindTexImage dispatcher. id = 16 + * eglBindTexImage dispatcher. id = 15 */ static uint8_t* yagl_func_eglBindTexImage(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -270,7 +256,7 @@ static uint8_t* yagl_func_eglBindTexImage(struct yagl_thread_state *ts, } /* - * eglReleaseTexImage dispatcher. id = 17 + * eglReleaseTexImage dispatcher. id = 16 */ static uint8_t* yagl_func_eglReleaseTexImage(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -287,23 +273,7 @@ static uint8_t* yagl_func_eglReleaseTexImage(struct yagl_thread_state *ts, } /* - * 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, @@ -321,7 +291,7 @@ static uint8_t* yagl_func_eglCreateContext(struct yagl_thread_state *ts, } /* - * eglDestroyContext dispatcher. id = 20 + * eglDestroyContext dispatcher. id = 18 */ static uint8_t* yagl_func_eglDestroyContext(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -337,7 +307,7 @@ static uint8_t* yagl_func_eglDestroyContext(struct yagl_thread_state *ts, } /* - * eglMakeCurrent dispatcher. id = 21 + * eglMakeCurrent dispatcher. id = 19 */ static uint8_t* yagl_func_eglMakeCurrent(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -355,7 +325,7 @@ static uint8_t* yagl_func_eglMakeCurrent(struct yagl_thread_state *ts, } /* - * eglQueryContext dispatcher. id = 22 + * eglQueryContext dispatcher. id = 20 */ static uint8_t* yagl_func_eglQueryContext(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -373,7 +343,7 @@ static uint8_t* yagl_func_eglQueryContext(struct yagl_thread_state *ts, } /* - * eglWaitGL dispatcher. id = 23 + * eglWaitGL dispatcher. id = 21 */ static uint8_t* yagl_func_eglWaitGL(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -387,7 +357,7 @@ static uint8_t* yagl_func_eglWaitGL(struct yagl_thread_state *ts, } /* - * eglWaitNative dispatcher. id = 24 + * eglWaitNative dispatcher. id = 22 */ static uint8_t* yagl_func_eglWaitNative(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -402,7 +372,7 @@ static uint8_t* yagl_func_eglWaitNative(struct yagl_thread_state *ts, } /* - * eglSwapBuffers dispatcher. id = 25 + * eglSwapBuffers dispatcher. id = 23 */ static uint8_t* yagl_func_eglSwapBuffers(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -418,7 +388,7 @@ static uint8_t* yagl_func_eglSwapBuffers(struct yagl_thread_state *ts, } /* - * eglCopyBuffers dispatcher. id = 26 + * eglCopyBuffers dispatcher. id = 24 */ static uint8_t* yagl_func_eglCopyBuffers(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -435,7 +405,7 @@ static uint8_t* yagl_func_eglCopyBuffers(struct yagl_thread_state *ts, } /* - * eglCreateWindowSurfaceOffscreenYAGL dispatcher. id = 27 + * eglCreateWindowSurfaceOffscreenYAGL dispatcher. id = 25 */ static uint8_t* yagl_func_eglCreateWindowSurfaceOffscreenYAGL(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -456,7 +426,7 @@ static uint8_t* yagl_func_eglCreateWindowSurfaceOffscreenYAGL(struct yagl_thread } /* - * eglCreatePbufferSurfaceOffscreenYAGL dispatcher. id = 28 + * eglCreatePbufferSurfaceOffscreenYAGL dispatcher. id = 26 */ static uint8_t* yagl_func_eglCreatePbufferSurfaceOffscreenYAGL(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -477,7 +447,7 @@ static uint8_t* yagl_func_eglCreatePbufferSurfaceOffscreenYAGL(struct yagl_threa } /* - * eglCreatePixmapSurfaceOffscreenYAGL dispatcher. id = 29 + * eglCreatePixmapSurfaceOffscreenYAGL dispatcher. id = 27 */ static uint8_t* yagl_func_eglCreatePixmapSurfaceOffscreenYAGL(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -498,7 +468,7 @@ static uint8_t* yagl_func_eglCreatePixmapSurfaceOffscreenYAGL(struct yagl_thread } /* - * eglResizeOffscreenSurfaceYAGL dispatcher. id = 30 + * eglResizeOffscreenSurfaceYAGL dispatcher. id = 28 */ static uint8_t* yagl_func_eglResizeOffscreenSurfaceYAGL(struct yagl_thread_state *ts, uint8_t *out_buff, @@ -517,7 +487,7 @@ static uint8_t* yagl_func_eglResizeOffscreenSurfaceYAGL(struct yagl_thread_state 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, @@ -530,14 +500,12 @@ yagl_api_func yagl_egl_api_funcs[] = { &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, diff --git a/hw/yagl_apis/egl/yagl_host_egl_calls.c b/hw/yagl_apis/egl/yagl_host_egl_calls.c index 7086af3fd4..16cd1dd302 100644 --- a/hw/yagl_apis/egl/yagl_host_egl_calls.c +++ b/hw/yagl_apis/egl/yagl_host_egl_calls.c @@ -623,10 +623,14 @@ EGLBoolean yagl_host_eglChooseConfig(yagl_host_handle dpy_, } 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); @@ -881,11 +885,6 @@ EGLBoolean yagl_host_eglBindAPI(EGLenum api) return EGL_TRUE; } -EGLenum yagl_host_eglQueryAPI(void) -{ - return egl_api_ts->api; -} - EGLBoolean yagl_host_eglWaitClient(void) { EGLBoolean ret = EGL_FALSE; @@ -993,12 +992,6 @@ EGLBoolean yagl_host_eglReleaseTexImage(yagl_host_handle dpy, 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_, @@ -1254,18 +1247,102 @@ out: 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); @@ -1364,11 +1441,63 @@ out: 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_, @@ -1475,7 +1604,122 @@ yagl_host_handle yagl_host_eglCreatePbufferSurfaceOffscreenYAGL(yagl_host_handle 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_, diff --git a/hw/yagl_apis/egl/yagl_host_egl_calls.h b/hw/yagl_apis/egl/yagl_host_egl_calls.h index 937246abb8..8f2e488d7a 100644 --- a/hw/yagl_apis/egl/yagl_host_egl_calls.h +++ b/hw/yagl_apis/egl/yagl_host_egl_calls.h @@ -67,16 +67,16 @@ EGLBoolean yagl_host_eglMakeCurrent(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_, diff --git a/hw/yagl_apis/gles/yagl_gles_buffer.c b/hw/yagl_apis/gles/yagl_gles_buffer.c index 21aa73b2be..3fe4ebd325 100644 --- a/hw/yagl_apis/gles/yagl_gles_buffer.c +++ b/hw/yagl_apis/gles/yagl_gles_buffer.c @@ -329,3 +329,48 @@ bool yagl_gles_buffer_transfer(struct yagl_gles_buffer *buffer, 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; +} diff --git a/hw/yagl_apis/gles/yagl_gles_buffer.h b/hw/yagl_apis/gles/yagl_gles_buffer.h index de9113af01..944b570bfe 100644 --- a/hw/yagl_apis/gles/yagl_gles_buffer.h +++ b/hw/yagl_apis/gles/yagl_gles_buffer.h @@ -47,6 +47,8 @@ struct yagl_gles_buffer GLint size; void *data; GLenum usage; + + bool was_bound; }; struct yagl_gles_buffer @@ -88,4 +90,12 @@ bool yagl_gles_buffer_transfer(struct yagl_gles_buffer *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 diff --git a/hw/yagl_apis/gles/yagl_gles_framebuffer.c b/hw/yagl_apis/gles/yagl_gles_framebuffer.c index 59b5095be5..e7237c8509 100644 --- a/hw/yagl_apis/gles/yagl_gles_framebuffer.c +++ b/hw/yagl_apis/gles/yagl_gles_framebuffer.c @@ -118,6 +118,7 @@ bool yagl_gles_framebuffer_texture2d(struct yagl_gles_framebuffer *fb, yagl_object_name texture_local_name) { yagl_gles_framebuffer_attachment framebuffer_attachment; + GLenum squashed_textarget; if (!yagl_gles_validate_framebuffer_attachment(attachment, &framebuffer_attachment)) { @@ -128,7 +129,12 @@ bool yagl_gles_framebuffer_texture2d(struct yagl_gles_framebuffer *fb, 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; } @@ -155,3 +161,64 @@ bool yagl_gles_framebuffer_texture2d(struct yagl_gles_framebuffer *fb, 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; +} diff --git a/hw/yagl_apis/gles/yagl_gles_framebuffer.h b/hw/yagl_apis/gles/yagl_gles_framebuffer.h index e7ef3e2c3d..55dde6b090 100644 --- a/hw/yagl_apis/gles/yagl_gles_framebuffer.h +++ b/hw/yagl_apis/gles/yagl_gles_framebuffer.h @@ -28,6 +28,8 @@ struct yagl_gles_framebuffer QemuMutex mutex; struct yagl_gles_framebuffer_attachment_state attachment_states[YAGL_NUM_GLES_FRAMEBUFFER_ATTACHMENTS]; + + bool was_bound; }; struct yagl_gles_framebuffer @@ -58,4 +60,13 @@ bool yagl_gles_framebuffer_texture2d(struct yagl_gles_framebuffer *fb, 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 diff --git a/hw/yagl_apis/gles/yagl_gles_renderbuffer.c b/hw/yagl_apis/gles/yagl_gles_renderbuffer.c index 48feda7426..9ee383c814 100644 --- a/hw/yagl_apis/gles/yagl_gles_renderbuffer.c +++ b/hw/yagl_apis/gles/yagl_gles_renderbuffer.c @@ -10,6 +10,8 @@ static void yagl_gles_renderbuffer_destroy(struct yagl_ref *ref) rb->driver_ps->DeleteRenderbuffers(rb->driver_ps, 1, &rb->global_name); } + qemu_mutex_destroy(&rb->mutex); + yagl_object_cleanup(&rb->base); g_free(rb); @@ -30,6 +32,8 @@ struct yagl_gles_renderbuffer rb->driver_ps = driver_ps; rb->global_name = global_name; + qemu_mutex_init(&rb->mutex); + return rb; } @@ -46,3 +50,25 @@ void yagl_gles_renderbuffer_release(struct yagl_gles_renderbuffer *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; +} diff --git a/hw/yagl_apis/gles/yagl_gles_renderbuffer.h b/hw/yagl_apis/gles/yagl_gles_renderbuffer.h index 9a5a8eb911..9bdc52fcb2 100644 --- a/hw/yagl_apis/gles/yagl_gles_renderbuffer.h +++ b/hw/yagl_apis/gles/yagl_gles_renderbuffer.h @@ -15,6 +15,10 @@ struct yagl_gles_renderbuffer struct yagl_gles_driver_ps *driver_ps; yagl_object_name global_name; + + QemuMutex mutex; + + bool was_bound; }; struct yagl_gles_renderbuffer @@ -30,4 +34,8 @@ void yagl_gles_renderbuffer_acquire(struct yagl_gles_renderbuffer *rb); */ 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 diff --git a/hw/yagl_apis/gles/yagl_gles_validate.c b/hw/yagl_apis/gles/yagl_gles_validate.c index 7e9ab8565e..b1ad28fcd8 100644 --- a/hw/yagl_apis/gles/yagl_gles_validate.c +++ b/hw/yagl_apis/gles/yagl_gles_validate.c @@ -90,3 +90,25 @@ bool yagl_gles_validate_framebuffer_attachment(GLenum attachment, 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; +} diff --git a/hw/yagl_apis/gles/yagl_gles_validate.h b/hw/yagl_apis/gles/yagl_gles_validate.h index 2db5419261..5abf8dd3d8 100644 --- a/hw/yagl_apis/gles/yagl_gles_validate.h +++ b/hw/yagl_apis/gles/yagl_gles_validate.h @@ -17,4 +17,7 @@ bool yagl_gles_validate_texture_target(GLenum target, 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 diff --git a/hw/yagl_apis/gles/yagl_host_gles_calls.c b/hw/yagl_apis/gles/yagl_host_gles_calls.c index a0e0d07111..f5941e1065 100644 --- a/hw/yagl_apis/gles/yagl_host_gles_calls.c +++ b/hw/yagl_apis/gles/yagl_host_gles_calls.c @@ -177,6 +177,10 @@ void yagl_host_glBindBuffer(GLenum target, goto out; } + if (buffer_obj) { + yagl_gles_buffer_set_bound(buffer_obj); + } + out: yagl_gles_buffer_release(buffer_obj); } @@ -900,9 +904,38 @@ out: 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) @@ -994,16 +1027,38 @@ out: 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, @@ -1016,7 +1071,21 @@ 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) @@ -1027,7 +1096,21 @@ 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) @@ -1213,9 +1296,28 @@ void yagl_host_glTexParameterf(GLenum target, 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, @@ -1229,9 +1331,28 @@ 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, @@ -1313,3 +1434,65 @@ GLuint yagl_host_glGetExtensionStringYAGL(target_ulong /* GLchar* */ str_) 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; +} diff --git a/hw/yagl_apis/gles/yagl_host_gles_calls.h b/hw/yagl_apis/gles/yagl_host_gles_calls.h index d48c1c90c2..fc33259ab1 100644 --- a/hw/yagl_apis/gles/yagl_host_gles_calls.h +++ b/hw/yagl_apis/gles/yagl_host_gles_calls.h @@ -91,7 +91,7 @@ void yagl_host_glGetBooleanv(GLenum pname, 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_); @@ -99,10 +99,10 @@ void yagl_host_glGetIntegerv(GLenum pname, 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); @@ -147,13 +147,13 @@ void yagl_host_glTexParameterf(GLenum target, 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, @@ -168,5 +168,10 @@ void yagl_host_glViewport(GLint x, 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 diff --git a/hw/yagl_apis/gles1/yagl_gles1_calls.c b/hw/yagl_apis/gles1/yagl_gles1_calls.c index 23daf3be59..08d3054c20 100644 --- a/hw/yagl_apis/gles1/yagl_gles1_calls.c +++ b/hw/yagl_apis/gles1/yagl_gles1_calls.c @@ -2270,7 +2270,25 @@ static uint8_t* yagl_func_glGetExtensionStringYAGL(struct yagl_thread_state *ts, 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, @@ -2416,5 +2434,6 @@ yagl_api_func yagl_gles1_api_funcs[] = { &yagl_func_glTranslatex, &yagl_func_glVertexPointer, &yagl_func_glViewport, - &yagl_func_glGetExtensionStringYAGL + &yagl_func_glGetExtensionStringYAGL, + &yagl_func_glEGLImageTargetTexture2DYAGL }; diff --git a/hw/yagl_apis/gles2/yagl_gles2_calls.c b/hw/yagl_apis/gles2/yagl_gles2_calls.c index 82d2a4bf64..baf01de5e0 100644 --- a/hw/yagl_apis/gles2/yagl_gles2_calls.c +++ b/hw/yagl_apis/gles2/yagl_gles2_calls.c @@ -2265,7 +2265,25 @@ static uint8_t* yagl_func_glGetExtensionStringYAGL(struct yagl_thread_state *ts, 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, @@ -2409,5 +2427,6 @@ yagl_api_func yagl_gles2_api_funcs[] = { &yagl_func_glVertexAttrib4fv, &yagl_func_glVertexAttribPointer, &yagl_func_glViewport, - &yagl_func_glGetExtensionStringYAGL + &yagl_func_glGetExtensionStringYAGL, + &yagl_func_glEGLImageTargetTexture2DYAGL }; diff --git a/hw/yagl_apis/gles2/yagl_gles2_context.c b/hw/yagl_apis/gles2/yagl_gles2_context.c index 73de5fef2d..50f366aa79 100644 --- a/hw/yagl_apis/gles2/yagl_gles2_context.c +++ b/hw/yagl_apis/gles2/yagl_gles2_context.c @@ -223,7 +223,7 @@ 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_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 "; diff --git a/hw/yagl_apis/gles2/yagl_gles2_program.c b/hw/yagl_apis/gles2/yagl_gles2_program.c index f0feeb57d6..ef10d277db 100644 --- a/hw/yagl_apis/gles2/yagl_gles2_program.c +++ b/hw/yagl_apis/gles2/yagl_gles2_program.c @@ -175,6 +175,24 @@ void yagl_gles2_program_get_active_uniform(struct yagl_gles2_program *program, 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) { diff --git a/hw/yagl_apis/gles2/yagl_gles2_program.h b/hw/yagl_apis/gles2/yagl_gles2_program.h index 8f9519e09a..d4840e3953 100644 --- a/hw/yagl_apis/gles2/yagl_gles2_program.h +++ b/hw/yagl_apis/gles2/yagl_gles2_program.h @@ -67,6 +67,13 @@ void yagl_gles2_program_get_active_uniform(struct yagl_gles2_program *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. */ diff --git a/hw/yagl_apis/gles2/yagl_gles2_shader.c b/hw/yagl_apis/gles2/yagl_gles2_shader.c index 8040589713..87424d7fba 100644 --- a/hw/yagl_apis/gles2/yagl_gles2_shader.c +++ b/hw/yagl_apis/gles2/yagl_gles2_shader.c @@ -247,6 +247,30 @@ void yagl_gles2_shader_get_param(struct yagl_gles2_shader *shader, 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) { diff --git a/hw/yagl_apis/gles2/yagl_gles2_shader.h b/hw/yagl_apis/gles2/yagl_gles2_shader.h index a12aacaa7d..10d1da615f 100644 --- a/hw/yagl_apis/gles2/yagl_gles2_shader.h +++ b/hw/yagl_apis/gles2/yagl_gles2_shader.h @@ -34,6 +34,16 @@ void yagl_gles2_shader_get_param(struct yagl_gles2_shader *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. */ diff --git a/hw/yagl_apis/gles2/yagl_host_gles2_calls.c b/hw/yagl_apis/gles2/yagl_host_gles2_calls.c index 4ab13406c3..6db2eb646c 100644 --- a/hw/yagl_apis/gles2/yagl_host_gles2_calls.c +++ b/hw/yagl_apis/gles2/yagl_host_gles2_calls.c @@ -48,6 +48,36 @@ YAGL_DEFINE_TLS(struct yagl_gles2_api_ts*, gles2_api_ts); 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) @@ -274,6 +304,10 @@ void yagl_host_glBindFramebuffer(GLenum target, 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); } @@ -310,6 +344,10 @@ void yagl_host_glBindRenderbuffer(GLenum target, 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); } @@ -890,10 +928,56 @@ out: 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, @@ -934,9 +1018,34 @@ out: 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, @@ -975,17 +1084,62 @@ out: 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, @@ -1024,40 +1178,155 @@ out: 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, @@ -1097,9 +1366,45 @@ out: 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, @@ -1126,28 +1431,8 @@ 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_) { @@ -1164,29 +1449,108 @@ out: 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) @@ -1236,7 +1600,12 @@ void yagl_host_glShaderBinary(GLsizei n, 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, @@ -1732,7 +2101,22 @@ out: 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, diff --git a/hw/yagl_apis/gles2/yagl_host_gles2_calls.h b/hw/yagl_apis/gles2/yagl_host_gles2_calls.h index f557f1006d..0da0068e44 100644 --- a/hw/yagl_apis/gles2/yagl_host_gles2_calls.h +++ b/hw/yagl_apis/gles2/yagl_host_gles2_calls.h @@ -73,39 +73,39 @@ void yagl_host_glGetActiveUniform(GLuint program, 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); @@ -116,13 +116,13 @@ int yagl_host_glGetUniformLocation(GLuint program, 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); diff --git a/hw/yagl_drivers/egl_glx/yagl_egl_glx.c b/hw/yagl_drivers/egl_glx/yagl_egl_glx.c index c584404abc..b47f521930 100644 --- a/hw/yagl_drivers/egl_glx/yagl_egl_glx.c +++ b/hw/yagl_drivers/egl_glx/yagl_egl_glx.c @@ -345,7 +345,7 @@ static EGLSurface yagl_egl_glx_pbuffer_surface_create(struct yagl_egl_driver_ps 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 }; diff --git a/hw/yagl_drivers/gles_ogl/yagl_gles_ogl.c b/hw/yagl_drivers/gles_ogl/yagl_gles_ogl.c index 977c272e6b..998e866a93 100644 --- a/hw/yagl_drivers/gles_ogl/yagl_gles_ogl.c +++ b/hw/yagl_drivers/gles_ogl/yagl_gles_ogl.c @@ -81,6 +81,8 @@ struct yagl_gles_ogl 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) @@ -156,6 +158,8 @@ YAGL_GLES_OGL_PROC_IMPL4(yagl_gles_driver_ps, yagl_gles_ogl_ps, yagl_gles_ogl, F 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, @@ -243,6 +247,8 @@ struct yagl_gles_ogl_ps 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); @@ -349,6 +355,8 @@ struct yagl_gles_ogl 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); diff --git a/hw/yagl_gles_driver.h b/hw/yagl_gles_driver.h index e293cb519a..7298865eba 100644 --- a/hw/yagl_gles_driver.h +++ b/hw/yagl_gles_driver.h @@ -143,6 +143,8 @@ struct yagl_gles_driver_ps 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, diff --git a/hw/yagl_mem.h b/hw/yagl_mem.h index 6bef8542ef..91b7622f4f 100644 --- a/hw/yagl_mem.h +++ b/hw/yagl_mem.h @@ -51,4 +51,10 @@ char *yagl_mem_get_string(struct yagl_thread_state *ts, target_ulong va); #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 diff --git a/hw/yagl_version.h b/hw/yagl_version.h index 2c7aee3f7b..0edf7f701e 100644 --- a/hw/yagl_version.h +++ b/hw/yagl_version.h @@ -6,6 +6,6 @@ /* * Whenever protocol changes be sure to bump this. */ -#define YAGL_VERSION 8 +#define YAGL_VERSION 9 #endif