Hi, I do not know if it's the right place for this, but I sent an email to the Mesa-users mailing list explaining the problem, and I have no answers, so if anyone can help, this is what happens:
I'm using Mesa 9.1, EGL and xcb, to make texture from pixmap. Using EGL_KHR_image_pixmap, i get errors in textures. I have also checked texture_from_pixmap in the EGL demos, and the demo not work. I have no errors with Mesa 9.0, my test code and demo work well. Linux: archlinux Mesa: mesa-9.1-2, (mesa-demos from git) Drivers: intel-dri 9.1-2, xf86-video-intel 2.21.3-1 Kernel: 3.8.0-2-ARCH (same results with kernel 3.7.9) I've re-checked the test-code with mesa 9.0, and the only error is that the texture (texture_a) is upside down... Test code: // gcc -Wall -O3 egl-xcb-texture.c -o egl-xcb-texture -lEGL -lGLESv1_CM -lGLESv2 -lxcb -lxcb-util #include <xcb/xcb.h> #include <xcb/xcb_util.h> #include <GLES/gl.h> #include <GLES/glext.h> #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> //#include <GLES3/gl3.h> //#include <GLES3/gl3ext.h> #include <EGL/egl.h> #include <EGL/eglext.h> #include <stdio.h> #include <stdlib.h> #include <string.h> float vert_tex_data[] = { 1.00f, 1.00f, 0.00f, // Position 0 1.00f, 1.00f, // TexCoord 0 -1.00f, 1.00f, 0.00f, // Position 1 0.00f, 1.00f, // TexCoord 1 -1.00f, -1.00f, 0.00f, // Position 2 0.00f, 0.00f, // TexCoord 2 1.00f, -1.00f, 0.00f, // Position 3 1.00f, 0.00f}; // TexCoord 3 const GLushort index_data[] = {0, 1, 2, 2, 3, 0,}; struct ctx_t { xcb_connection_t *conn; int num_scr; xcb_screen_t *screen; const xcb_setup_t *setup; xcb_generic_event_t *xcb_event; xcb_window_t window; xcb_pixmap_t xpix; GLuint texture_a; GLuint texture_b; EGLDisplay egl_dpy; EGLConfig egl_cfg; EGLContext egl_context; EGLSurface egl_surface; GLuint shader_program; GLint loc_v_position; GLint loc_tex_coord; GLint loc_texture; PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES; }; void new_xwindow(struct ctx_t *ctx) { uint32_t values[5], mask; xcb_colormap_t colormap = 0; xcb_visualtype_t *visual = NULL; xcb_visualid_t visual_id; visual = xcb_aux_find_visual_by_attrs(ctx->screen, XCB_VISUAL_CLASS_TRUE_COLOR, 32); visual_id = visual->visual_id; colormap = xcb_generate_id(ctx->conn); xcb_create_colormap(ctx->conn, XCB_COLORMAP_ALLOC_NONE, colormap, ctx->screen->root, visual_id); mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP; values[0] = 0; values[1] = 0; values[2] = XCB_GRAVITY_NORTH_WEST; values[3] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS; values[4] = colormap; ctx->window = xcb_generate_id(ctx->conn); xcb_create_window(ctx->conn, 32, ctx->window, ctx->screen->root, 0, 0, 800, 600, 0, //border XCB_WINDOW_CLASS_INPUT_OUTPUT, visual_id, mask, values); xcb_free_colormap(ctx->conn, colormap); xcb_flush(ctx->conn); } void make_pixmap(struct ctx_t *ctx, uint16_t w, uint16_t h, uint8_t depth) { xcb_gcontext_t gc = 0; xcb_rectangle_t rec = {0, 0, w - 1, h - 1}; xcb_arc_t arc[] = {{0, 0, w - 1, h - 1, 0, 90 * 64}, {0, 0, w - 1, h - 1, 90 * 64, 90 * 64}, {0, 0, w - 1, h - 1, 180 * 64, 90 * 64}, {0, 0, w - 1, h - 1, 270 * 64, 90 * 64}}; uint32_t red = 0xff0000, yellow = 0x808000, blue = 0x0000ff, green = 0x00ff00, violet = 0xff00ff; ctx->xpix = xcb_generate_id(ctx->conn); xcb_create_pixmap(ctx->conn, depth, ctx->xpix, ctx->screen->root, w, h); gc = xcb_generate_id(ctx->conn); xcb_create_gc(ctx->conn, gc, ctx->xpix, XCB_GC_FOREGROUND, &yellow); xcb_poly_fill_rectangle(ctx->conn, ctx->xpix, gc, 1, &rec); xcb_change_gc(ctx->conn, gc, XCB_GC_FOREGROUND, &blue); xcb_poly_rectangle(ctx->conn, ctx->xpix, gc, 1, &rec); xcb_change_gc(ctx->conn, gc, XCB_GC_FOREGROUND, &red); xcb_poly_fill_arc(ctx->conn, ctx->xpix, gc, 1, &arc[0]); xcb_change_gc(ctx->conn, gc, XCB_GC_FOREGROUND, &blue); xcb_poly_fill_arc(ctx->conn, ctx->xpix, gc, 1, &arc[1]); xcb_change_gc(ctx->conn, gc, XCB_GC_FOREGROUND, &green); xcb_poly_fill_arc(ctx->conn, ctx->xpix, gc, 1, &arc[2]); xcb_change_gc(ctx->conn, gc, XCB_GC_FOREGROUND, &violet); xcb_poly_fill_arc(ctx->conn, ctx->xpix, gc, 1, &arc[3]); xcb_copy_area(ctx->conn, ctx->xpix, ctx->window, gc, 0, 0, 0, 0, w, h); xcb_free_gc(ctx->conn, gc); } void mirror(uint8_t *src, int len, int stride, uint8_t *dst) { uint8_t *out = dst + len - stride; uint8_t *in = NULL; for (in = src; in < src + len; in += stride) { memcpy(out, in, stride); out -= stride; } } //Esta textura anda ok. //texture ok int make_texture_b(struct ctx_t *ctx) { xcb_get_geometry_cookie_t g_cookie; xcb_get_geometry_reply_t *g_reply = NULL; uint16_t w, h; xcb_get_image_cookie_t cookie; xcb_get_image_reply_t *reply =NULL; uint8_t *pixels = NULL; uint8_t *buffer = NULL; int len, stride; g_cookie = xcb_get_geometry(ctx->conn, ctx->xpix); g_reply = xcb_get_geometry_reply(ctx->conn, g_cookie, NULL); if (!g_reply) return -1; w = g_reply->width; h = g_reply->height; free(g_reply); cookie = xcb_get_image(ctx->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, ctx->xpix, 0, 0, w, h, 0xffffffff); reply = xcb_get_image_reply(ctx->conn, cookie, NULL); if (!reply) return -1; pixels = xcb_get_image_data(reply); len = xcb_get_image_data_length(reply); stride = w * 4; buffer = malloc(len); mirror(pixels, len, stride, buffer); free(reply); glGenTextures(1, &ctx->texture_b); glBindTexture(GL_TEXTURE_2D, ctx->texture_b); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer); free(buffer); return 0; } //Esta textura anda mal. //texture bad void make_texture_a(struct ctx_t *ctx) { EGLImageKHR khrimg = NULL; const EGLint attr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, //EGL_GL_TEXTURE_LEVEL_KHR, 0, // mip map level to reference EGL_NONE}; khrimg = ctx->eglCreateImageKHR(ctx->egl_dpy, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)(uintptr_t)ctx->xpix, attr); glGenTextures(1, &ctx->texture_a); glBindTexture(GL_TEXTURE_2D, ctx->texture_a); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ctx->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)khrimg); ctx->eglDestroyImageKHR(ctx->egl_dpy, khrimg); } void init_xcb(struct ctx_t *ctx) { ctx->conn = xcb_connect(NULL, &ctx->num_scr); ctx->screen = xcb_aux_get_screen(ctx->conn, ctx->num_scr); ctx->setup = xcb_get_setup(ctx->conn); xcb_flush(ctx->conn); } void init_egl(struct ctx_t *ctx) { EGLint attr[] = {EGL_BUFFER_SIZE, 32, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT | EGL_OPENGL_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PIXMAP_BIT, EGL_MATCH_NATIVE_PIXMAP, (GLint)ctx->screen->root, EGL_NONE}; //ctx->egl_dpy = eglGetDisplay((EGLNativeDisplayType)NULL); ctx->egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(ctx->egl_dpy, NULL, NULL); EGLint num_config; eglChooseConfig(ctx->egl_dpy, attr, &ctx->egl_cfg, 1, &num_config); ctx->egl_surface = eglCreateWindowSurface(ctx->egl_dpy, ctx->egl_cfg, ctx->window, NULL); ctx->egl_context = eglCreateContext(ctx->egl_dpy, ctx->egl_cfg, EGL_NO_CONTEXT, (EGLint[]){EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}); eglMakeCurrent(ctx->egl_dpy, ctx->egl_surface, ctx->egl_surface, ctx->egl_context); eglBindAPI(EGL_OPENGL_ES_API); ctx->eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR"); ctx->eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR"); ctx->glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES"); } void init_shaders(struct ctx_t *ctx) { const char *vertx_src = " \ attribute vec4 v_position; \ attribute vec2 tex_coord; \ varying mediump vec2 v_tex_coord; \ \ void main() \ { \ gl_Position = v_position; \ v_tex_coord = tex_coord; \ }"; const char *frag_src = " \ varying mediump vec2 v_tex_coord; \ uniform sampler2D texture; \ \ void main() \ { \ gl_FragColor = texture2D(texture, v_tex_coord); \ }"; GLuint vertex_shader, fragment_shader; ctx->shader_program = glCreateProgram(); vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, &vertx_src, NULL); glCompileShader(vertex_shader); fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, &frag_src, NULL); glCompileShader(fragment_shader); glAttachShader(ctx->shader_program, vertex_shader); glAttachShader(ctx->shader_program, fragment_shader); glLinkProgram(ctx->shader_program); glDetachShader(ctx->shader_program, vertex_shader); glDetachShader(ctx->shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(fragment_shader); } void render(struct ctx_t *ctx) { glClear(GL_COLOR_BUFFER_BIT); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, index_data); eglSwapBuffers(ctx->egl_dpy, ctx->egl_surface); } int main() { struct ctx_t ctx; init_xcb(&ctx); new_xwindow(&ctx); xcb_map_window(ctx.conn, ctx.window); xcb_flush(ctx.conn); make_pixmap(&ctx, 400, 200, 32); xcb_flush(ctx.conn); init_egl(&ctx); make_texture_a(&ctx); make_texture_b(&ctx); init_shaders(&ctx); glUseProgram(ctx.shader_program); ctx.loc_v_position = glGetAttribLocation(ctx.shader_program, "v_position"); ctx.loc_texture = glGetUniformLocation(ctx.shader_program, "texture"); ctx.loc_tex_coord = glGetAttribLocation(ctx.shader_program, "tex_coord"); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, ctx.texture_a); // Set the sampler texture unit to 0 glUniform1i(ctx.loc_texture, 0); glEnableVertexAttribArray(ctx.loc_v_position); glVertexAttribPointer(ctx.loc_v_position, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vert_tex_data); // set the texture coords glEnableVertexAttribArray(ctx.loc_tex_coord); glVertexAttribPointer(ctx.loc_tex_coord, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vert_tex_data[3]); glViewport(0, 0, 800, 600); xcb_flush(ctx.conn); for (;;) { ctx.xcb_event = xcb_wait_for_event(ctx.conn); if (xcb_connection_has_error(ctx.conn)) goto out; uint8_t ev_type; ev_type = ctx.xcb_event->response_type & ~0x80; if (ev_type == XCB_KEY_PRESS) { xcb_key_press_event_t *ev = (xcb_key_press_event_t *)ctx.xcb_event; if (ev->detail == 9) { //Esc goto out; } //key a ---> show bad texture if (ev->detail == 38) { //key a glBindTexture(GL_TEXTURE_2D, ctx.texture_a); render(&ctx); } //key b ---> show texture ok if (ev->detail == 56) { //key b glBindTexture(GL_TEXTURE_2D, ctx.texture_b); render(&ctx); } } free(ctx.xcb_event); ctx.xcb_event = NULL; xcb_flush(ctx.conn); } out: glDisableVertexAttribArray(ctx.loc_v_position); glDisableVertexAttribArray(ctx.loc_tex_coord); glDeleteTextures(1, &ctx.texture_a); glDeleteTextures(1, &ctx.texture_b); glDeleteProgram(ctx.shader_program); eglDestroySurface(ctx.egl_dpy, ctx.egl_surface); eglMakeCurrent(ctx.egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(ctx.egl_dpy, ctx.egl_context); eglTerminate(ctx.egl_dpy); eglReleaseThread(); if (ctx.xcb_event) free(ctx.xcb_event); xcb_free_pixmap(ctx.conn, ctx.xpix); xcb_destroy_window(ctx.conn, ctx.window); xcb_disconnect(ctx.conn); return 0; } original pixmap: http://www.freeimagehosting.net/33j4c texture ok: http://www.freeimagehosting.net/dzh2d texture bad: http://www.freeimagehosting.net/pnd7r I appreciate any help, thanks. Gabriel. (Sorry for my English, not my native language)
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev