vrend: BGRX between texture and EGL image is not copy compatible

When virglrenderer creates VIRGL_FORMAT_B8G8R8X8_UNORM texture, it
uses internal format GL_BGRA_EXT.

When Mesa imports dma_buf VIRGL_FORMAT_B8G8R8X8_UNORM/DRM|GBM_FORMAT_XRGB8888
it uses internal format GL_RGB8.

These formats are not copy compatible.

Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
macos/master
Dominik Behr 4 years ago
parent 45d1e4fa77
commit 4acd9f0e34
  1. 17
      src/vrend_formats.c
  2. 17
      src/vrend_renderer.c
  3. 5
      src/vrend_renderer.h

@ -869,12 +869,23 @@ static boolean format_compressed_compressed_copy_compatible(enum virgl_formats s
} }
boolean format_is_copy_compatible(enum virgl_formats src, enum virgl_formats dst, boolean format_is_copy_compatible(enum virgl_formats src, enum virgl_formats dst,
boolean allow_compressed) unsigned int flags)
{ {
int r; int r;
if (src == dst) if (src == dst) {
/* When Mesa imports dma_buf VIRGL_FORMAT_B8G8R8X8_UNORM/DRM|GBM_FORMAT_XRGB8888
* it uses internal format GL_RGB8.
* But when virglrenderer creates VIRGL_FORMAT_B8G8R8X8_UNORM texture, it
* uses internal format GL_BGRA_EXT.
* So the formats do not match when Mesa checks them internally.
*/
if (flags & VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE &&
(src == VIRGL_FORMAT_B8G8R8X8_UNORM ||
src == VIRGL_FORMAT_B8G8R8X8_UNORM_EMULATED))
return false;
return true; return true;
}
if (util_format_is_plain(src) && util_format_is_plain(dst)) { if (util_format_is_plain(src) && util_format_is_plain(dst)) {
const struct util_format_description *src_desc = util_format_description(src); const struct util_format_description *src_desc = util_format_description(src);
@ -882,7 +893,7 @@ boolean format_is_copy_compatible(enum virgl_formats src, enum virgl_formats dst
return util_is_format_compatible(src_desc, dst_desc); return util_is_format_compatible(src_desc, dst_desc);
} }
if (!allow_compressed) if (!(flags & VREND_COPY_COMPAT_FLAG_ALLOW_COMPRESSED))
return false; return false;
/* compressed-uncompressed */ /* compressed-uncompressed */

@ -8697,6 +8697,7 @@ void vrend_renderer_resource_copy_region(struct vrend_context *ctx,
struct vrend_resource *src_res, *dst_res; struct vrend_resource *src_res, *dst_res;
GLbitfield glmask = 0; GLbitfield glmask = 0;
GLint sy1, sy2, dy1, dy2; GLint sy1, sy2, dy1, dy2;
unsigned int comp_flags;
if (ctx->in_error) if (ctx->in_error)
return; return;
@ -8731,8 +8732,14 @@ void vrend_renderer_resource_copy_region(struct vrend_context *ctx,
return; return;
} }
comp_flags = VREND_COPY_COMPAT_FLAG_ALLOW_COMPRESSED;
if (src_res->egl_image)
comp_flags |= VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE;
if (dst_res->egl_image)
comp_flags ^= VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE;
if (has_feature(feat_copy_image) && if (has_feature(feat_copy_image) &&
format_is_copy_compatible(src_res->base.format,dst_res->base.format, true) && format_is_copy_compatible(src_res->base.format,dst_res->base.format, comp_flags) &&
src_res->base.nr_samples == dst_res->base.nr_samples) { src_res->base.nr_samples == dst_res->base.nr_samples) {
VREND_DEBUG(dbg_copy_resource, ctx, "COPY_REGION: use glCopyImageSubData\n"); VREND_DEBUG(dbg_copy_resource, ctx, "COPY_REGION: use glCopyImageSubData\n");
vrend_copy_sub_image(src_res, dst_res, src_level, src_box, vrend_copy_sub_image(src_res, dst_res, src_level, src_box,
@ -9123,6 +9130,7 @@ void vrend_renderer_blit(struct vrend_context *ctx,
uint32_t dst_handle, uint32_t src_handle, uint32_t dst_handle, uint32_t src_handle,
const struct pipe_blit_info *info) const struct pipe_blit_info *info)
{ {
unsigned int comp_flags = 0;
struct vrend_resource *src_res, *dst_res; struct vrend_resource *src_res, *dst_res;
src_res = vrend_renderer_ctx_res_lookup(ctx, src_handle); src_res = vrend_renderer_ctx_res_lookup(ctx, src_handle);
dst_res = vrend_renderer_ctx_res_lookup(ctx, dst_handle); dst_res = vrend_renderer_ctx_res_lookup(ctx, dst_handle);
@ -9170,6 +9178,11 @@ void vrend_renderer_blit(struct vrend_context *ctx,
info->dst.box.width, info->dst.box.height, info->dst.box.depth, info->dst.box.width, info->dst.box.height, info->dst.box.depth,
info->dst.level); info->dst.level);
if (src_res->egl_image)
comp_flags |= VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE;
if (dst_res->egl_image)
comp_flags ^= VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE;
/* The Gallium blit function can be called for a general blit that may /* The Gallium blit function can be called for a general blit that may
* scale, convert the data, and apply some rander states, or it is called via * scale, convert the data, and apply some rander states, or it is called via
* glCopyImageSubData. If the src or the dst image are equal, or the two * glCopyImageSubData. If the src or the dst image are equal, or the two
@ -9179,7 +9192,7 @@ void vrend_renderer_blit(struct vrend_context *ctx,
* normal blit. */ * normal blit. */
if (has_feature(feat_copy_image) && if (has_feature(feat_copy_image) &&
(!info->render_condition_enable || !ctx->sub->cond_render_gl_mode) && (!info->render_condition_enable || !ctx->sub->cond_render_gl_mode) &&
format_is_copy_compatible(info->src.format,info->dst.format, false) && format_is_copy_compatible(info->src.format,info->dst.format, comp_flags) &&
!info->scissor_enable && (info->filter == PIPE_TEX_FILTER_NEAREST) && !info->scissor_enable && (info->filter == PIPE_TEX_FILTER_NEAREST) &&
!info->alpha_blend && (info->mask == PIPE_MASK_RGBA) && !info->alpha_blend && (info->mask == PIPE_MASK_RGBA) &&
src_res->base.nr_samples == dst_res->base.nr_samples && src_res->base.nr_samples == dst_res->base.nr_samples &&

@ -464,8 +464,11 @@ void vrend_fb_bind_texture(struct vrend_resource *res,
int idx, int idx,
uint32_t level, uint32_t layer); uint32_t level, uint32_t layer);
bool vrend_format_is_emulated_alpha(enum virgl_formats format); bool vrend_format_is_emulated_alpha(enum virgl_formats format);
#define VREND_COPY_COMPAT_FLAG_ALLOW_COMPRESSED (1u << 0)
#define VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE (1u << 1)
boolean format_is_copy_compatible(enum virgl_formats src, enum virgl_formats dst, boolean format_is_copy_compatible(enum virgl_formats src, enum virgl_formats dst,
boolean allow_compressed); unsigned int flags);
/* blitter interface */ /* blitter interface */
void vrend_renderer_blit_gl(struct vrend_context *ctx, void vrend_renderer_blit_gl(struct vrend_context *ctx,

Loading…
Cancel
Save