Commit 0b74c7e7 authored by Ivaylo Dimitrov's avatar Ivaylo Dimitrov
Browse files

glamor: Fix rendering of pixmap textures backed by EGLImageKHR image



According to khronos documentation, "If <target> is not
TEXTURE_EXTERNAL_OES, the error INVALID_ENUM is generated." if
glEGLImageTargetTexture2DOES is called for an image created by using
EGL_KHR_image_pixmap extension. Not only that, but we must use
samplerExternalOES and not sampler2D to access such a texture from the
fragment shader. In addition we must require GL_OES_EGL_image_external from
the shader to be able to use the extension.

Fix the above issues by providing the correct texture unit to function
calls in glamor_create_texture_from_image(). Add a flag to
glamor_pixmap_fbo that will allow us to provide the correct texture unit
when binding that texture. Also, provide separate copy facet for fbos that
are created for GL_OES_EGL_image_external backed textures. Add a member to
glamor_program_location that allows us to select the correct sampler in the
fragment shader. Extend fs_template with extension member var used to
request the needed extensions in the fragment shader.

Tested on Motorola Droid4 with TI PVR DDK 1.17 closed blobs.

Signed-off-by: Ivaylo Dimitrov's avatarIvaylo Dimitrov <ivo.g.dimitrov.75@gmail.com>
parent 5c400cae
Pipeline #232564 passed with stages
in 4 minutes and 58 seconds
......@@ -165,7 +165,12 @@ glamor_bind_texture(glamor_screen_private *glamor_priv, GLenum texture,
glamor_pixmap_fbo *fbo, Bool destination_red)
{
glActiveTexture(texture);
glBindTexture(GL_TEXTURE_2D, fbo->tex);
#ifdef GLAMOR_HAS_GBM
if (fbo->ext_img)
glBindTexture(GL_TEXTURE_EXTERNAL_OES, fbo->tex);
else
#endif
glBindTexture(GL_TEXTURE_2D, fbo->tex);
/* If we're pulling data from a GL_RED texture, then whether we
* want to make it an A,0,0,0 result or a 0,0,0,R result depends
......
......@@ -57,6 +57,19 @@ static const glamor_facet glamor_facet_copyarea = {
.use = use_copyarea,
};
#ifdef GLAMOR_HAS_GBM
static const glamor_facet glamor_facet_copyarea_drm = {
"copy_area",
.extensions = "#extension GL_OES_EGL_image_external : require\n",
.vs_vars = "attribute vec2 primitive;\n",
.vs_exec = (GLAMOR_POS(gl_Position, primitive.xy)
" fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"),
.fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n",
.locations = glamor_program_location_fillsamp_drm | glamor_program_location_fillpos,
.use = use_copyarea,
};
#endif
/*
* Configure the copy plane program for the current operation
*/
......@@ -153,6 +166,24 @@ static const glamor_facet glamor_facet_copyplane = {
.use = use_copyplane,
};
#ifdef GLAMOR_HAS_GBM
static const glamor_facet glamor_facet_copyplane_drm = {
"copy_plane",
.version = 130,
.extensions = "#extension GL_OES_EGL_image_external : require\n",
.vs_vars = "attribute vec2 primitive;\n",
.vs_exec = (GLAMOR_POS(gl_Position, (primitive.xy))
" fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"),
.fs_exec = (" uvec4 bits = uvec4(round(texture2D(sampler, fill_pos) * bitmul));\n"
" if ((bits & bitplane) != uvec4(0,0,0,0))\n"
" gl_FragColor = fg;\n"
" else\n"
" gl_FragColor = bg;\n"),
.locations = glamor_program_location_fillsamp_drm|glamor_program_location_fillpos|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane,
.use = use_copyplane,
};
#endif
/*
* When all else fails, pull the bits out of the GPU and do the
* operation with fb
......@@ -386,10 +417,20 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src,
if (bitplane) {
prog = &glamor_priv->copy_plane_prog;
copy_facet = &glamor_facet_copyplane;
#ifdef GLAMOR_HAS_GBM
if (src_priv->fbo->ext_img)
copy_facet = &glamor_facet_copyplane_drm;
else
#endif
copy_facet = &glamor_facet_copyplane;
} else {
prog = &glamor_priv->copy_area_prog;
copy_facet = &glamor_facet_copyarea;
#ifdef GLAMOR_HAS_GBM
if (src_priv->fbo->ext_img)
copy_facet = &glamor_facet_copyarea_drm;
else
#endif
copy_facet = &glamor_facet_copyarea;
}
if (prog->failed)
......
......@@ -125,12 +125,12 @@ glamor_create_texture_from_image(ScreenPtr screen,
glamor_make_current(glamor_priv);
glGenTextures(1, texture);
glBindTexture(GL_TEXTURE_2D, *texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, *texture);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
glBindTexture(GL_TEXTURE_2D, 0);
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
return TRUE;
}
......@@ -241,8 +241,8 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap,
}
glamor_create_texture_from_image(screen, image, &texture);
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
glamor_set_pixmap_texture(pixmap, texture);
glamor_egl_set_pixmap_image(pixmap, image, used_modifiers);
glamor_set_pixmap_texture(pixmap, texture);
ret = TRUE;
done:
......
......@@ -280,6 +280,11 @@ glamor_pixmap_attach_fbo(PixmapPtr pixmap, glamor_pixmap_fbo *fbo)
pixmap_priv->fbo = fbo;
#ifdef GLAMOR_HAS_GBM
if (pixmap_priv->image)
fbo->ext_img = TRUE;
#endif
switch (pixmap_priv->type) {
case GLAMOR_TEXTURE_ONLY:
case GLAMOR_TEXTURE_DRM:
......
......@@ -319,6 +319,9 @@ typedef struct glamor_pixmap_fbo {
int height; /**< height in pixels */
GLenum format; /**< GL format used to create the texture. */
GLenum type; /**< GL type used to create the texture. */
#ifdef GLAMOR_HAS_GBM
Bool ext_img; /**< whether attached texture is EGLImageKHR backed */
#endif
} glamor_pixmap_fbo;
typedef struct glamor_pixmap_clipped_regions {
......
......@@ -117,6 +117,12 @@ static glamor_location_var location_vars[] = {
.location = glamor_program_location_fillsamp,
.fs_vars = "uniform sampler2D sampler;\n"
},
#ifdef GLAMOR_HAS_GBM
{
.location = glamor_program_location_fillsamp_drm,
.fs_vars = "uniform samplerExternalOES sampler;\n"
},
#endif
{
.location = glamor_program_location_fillpos,
.vs_vars = ("uniform vec2 fill_offset;\n"
......@@ -199,6 +205,9 @@ static const char vs_template[] =
static const char fs_template[] =
"%s" /* version */
#ifdef GLAMOR_HAS_GBM
"%s" /* extensions */
#endif
GLAMOR_DEFAULT_PRECISION
"%s" /* defines */
"%s" /* prim fs_vars */
......@@ -302,6 +311,9 @@ glamor_build_program(ScreenPtr screen,
if (asprintf(&fs_prog_string,
fs_template,
str(version_string),
#ifdef GLAMOR_HAS_GBM
str(prim->extensions),
#endif
str(defines),
str(prim->fs_vars),
str(fill->fs_vars),
......
......@@ -33,6 +33,9 @@ typedef enum {
glamor_program_location_bitplane = 32,
glamor_program_location_dash = 64,
glamor_program_location_atlas = 128,
#ifdef GLAMOR_HAS_GBM
glamor_program_location_fillsamp_drm = 256,
#endif
} glamor_program_location;
typedef enum {
......@@ -56,6 +59,9 @@ typedef Bool (*glamor_use_render) (CARD8 op, PicturePtr src, PicturePtr dst, gla
typedef struct {
const char *name;
const int version;
#ifdef GLAMOR_HAS_GBM
const char *extensions;
#endif
char *vs_defines;
char *fs_defines;
const char *vs_vars;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment