aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/dri/dri2.c28
-rw-r--r--src/mesa/state_tracker/st_atom_sampler.c3
-rw-r--r--src/mesa/state_tracker/st_atom_texture.c4
-rw-r--r--src/mesa/state_tracker/st_cb_eglimage.c89
-rw-r--r--src/mesa/state_tracker/st_program.h9
-rw-r--r--src/mesa/state_tracker/st_sampler_view.c4
6 files changed, 82 insertions, 55 deletions
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index 54a05c916f1..e6f0e40465a 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -738,7 +738,7 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
struct pipe_resource templ;
unsigned tex_usage = 0;
int i;
- bool is_yuv = util_format_is_yuv(map->pipe_format);
+ bool use_lowered = false;
if (pscreen->is_format_supported(pscreen, map->pipe_format, screen->target, 0, 0,
PIPE_BIND_RENDER_TARGET))
@@ -747,13 +747,14 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
PIPE_BIND_SAMPLER_VIEW))
tex_usage |= PIPE_BIND_SAMPLER_VIEW;
- if (!tex_usage && is_yuv) {
+ if (!tex_usage && util_format_is_yuv(map->pipe_format)) {
/* YUV format sampling can be emulated by the Mesa state tracker by
* using multiple samplers of varying formats.
* If no tex_usage is set and we detect a YUV format,
* test for support of the first plane's sampler format and
* add sampler view usage.
*/
+ use_lowered = true;
if (pscreen->is_format_supported(pscreen,
dri2_get_pipe_format_for_dri_format(map->planes[0].dri_format),
screen->target, 0, 0,
@@ -775,19 +776,20 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
templ.depth0 = 1;
templ.array_size = 1;
- for (i = num_handles - 1; i >= 0; i--) {
+ for (i = (use_lowered ? map->nplanes : num_handles) - 1; i >= 0; i--) {
struct pipe_resource *tex;
templ.width0 = width >> map->planes[i].width_shift;
templ.height0 = height >> map->planes[i].height_shift;
- if (is_yuv)
+ if (use_lowered)
templ.format = dri2_get_pipe_format_for_dri_format(map->planes[i].dri_format);
else
templ.format = map->pipe_format;
assert(templ.format != PIPE_FORMAT_NONE);
tex = pscreen->resource_from_handle(pscreen,
- &templ, &whandle[i], PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
+ &templ, &whandle[use_lowered ? map->planes[i].buffer_index : i],
+ PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
if (!tex) {
pipe_resource_reference(&img->texture, NULL);
FREE(img);
@@ -911,25 +913,23 @@ dri2_create_image_from_fd(__DRIscreen *_screen,
memset(whandles, 0, sizeof(whandles));
- for (i = 0; i < num_handles; i++) {
- int fdnum = i >= num_fds ? 0 : i;
- int index = i >= map->nplanes ? i : map->planes[i].buffer_index;
- if (fds[fdnum] < 0) {
+ for (i = 0; i < num_fds; i++) {
+ if (fds[i] < 0) {
err = __DRI_IMAGE_ERROR_BAD_ALLOC;
goto exit;
}
whandles[i].type = WINSYS_HANDLE_TYPE_FD;
- whandles[i].handle = (unsigned)fds[fdnum];
- whandles[i].stride = (unsigned)strides[index];
- whandles[i].offset = (unsigned)offsets[index];
+ whandles[i].handle = (unsigned)fds[i];
+ whandles[i].stride = (unsigned)strides[i];
+ whandles[i].offset = (unsigned)offsets[i];
whandles[i].format = map->pipe_format;
whandles[i].modifier = modifier;
- whandles[i].plane = index;
+ whandles[i].plane = i;
}
img = dri2_create_image_from_winsys(_screen, width, height, map,
- num_handles, whandles, loaderPrivate);
+ num_fds, whandles, loaderPrivate);
if(img == NULL) {
err = __DRI_IMAGE_ERROR_BAD_ALLOC;
goto exit;
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
index c0f43befa4d..b74d47b691f 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -304,7 +304,8 @@ update_shader_samplers(struct st_context *st,
st_get_texture_object(st->ctx, prog, unit);
struct pipe_sampler_state *sampler = samplers + unit;
- if (!stObj)
+ /* if resource format matches then YUV wasn't lowered */
+ if (!stObj || st_get_view_format(stObj) == stObj->pt->format)
continue;
switch (st_get_view_format(stObj)) {
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index ef54bc5a77f..5a0f91ccb14 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -182,6 +182,10 @@ update_textures(struct st_context *st,
/* use original view as template: */
tmpl = *sampler_views[unit];
+ /* if resource format matches then YUV wasn't lowered */
+ if (st_get_view_format(stObj) == stObj->pt->format)
+ continue;
+
switch (st_get_view_format(stObj)) {
case PIPE_FORMAT_NV12:
/* we need one additional R8G8 view: */
diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c
index d441c161449..5b03c5eb580 100644
--- a/src/mesa/state_tracker/st_cb_eglimage.c
+++ b/src/mesa/state_tracker/st_cb_eglimage.c
@@ -42,11 +42,12 @@
static bool
is_format_supported(struct pipe_screen *screen, enum pipe_format format,
unsigned nr_samples, unsigned nr_storage_samples,
- unsigned usage)
+ unsigned usage, bool *native_supported)
{
bool supported = screen->is_format_supported(screen, format, PIPE_TEXTURE_2D,
nr_samples, nr_storage_samples,
usage);
+ *native_supported = supported;
/* for sampling, some formats can be emulated.. it doesn't matter that
* the surface will have a format that the driver can't cope with because
@@ -115,7 +116,8 @@ is_format_supported(struct pipe_screen *screen, enum pipe_format format,
*/
static bool
st_get_egl_image(struct gl_context *ctx, GLeglImageOES image_handle,
- unsigned usage, const char *error, struct st_egl_image *out)
+ unsigned usage, const char *error, struct st_egl_image *out,
+ bool *native_supported)
{
struct st_context *st = st_context(ctx);
struct pipe_screen *screen = st->pipe->screen;
@@ -133,7 +135,8 @@ st_get_egl_image(struct gl_context *ctx, GLeglImageOES image_handle,
}
if (!is_format_supported(screen, out->format, out->texture->nr_samples,
- out->texture->nr_storage_samples, usage)) {
+ out->texture->nr_storage_samples, usage,
+ native_supported)) {
/* unable to specify a texture object using the specified EGL image */
pipe_resource_reference(&out->texture, NULL);
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(format not supported)", error);
@@ -180,10 +183,11 @@ st_egl_image_target_renderbuffer_storage(struct gl_context *ctx,
{
struct st_renderbuffer *strb = st_renderbuffer(rb);
struct st_egl_image stimg;
+ bool native_supported;
if (st_get_egl_image(ctx, image_handle, PIPE_BIND_RENDER_TARGET,
"glEGLImageTargetRenderbufferStorage",
- &stimg)) {
+ &stimg, &native_supported)) {
struct pipe_context *pipe = st_context(ctx)->pipe;
struct pipe_surface *ps, surf_tmpl;
@@ -212,7 +216,8 @@ st_bind_egl_image(struct gl_context *ctx,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage,
struct st_egl_image *stimg,
- bool tex_storage)
+ bool tex_storage,
+ bool native_supported)
{
struct st_context *st = st_context(ctx);
struct st_texture_object *stObj;
@@ -239,34 +244,39 @@ st_bind_egl_image(struct gl_context *ctx,
/* TODO RequiredTextureImageUnits should probably be reset back
* to 1 somewhere if different texture is bound??
*/
- switch (stimg->format) {
- case PIPE_FORMAT_NV12:
- texFormat = MESA_FORMAT_R_UNORM8;
- texObj->RequiredTextureImageUnits = 2;
- break;
- case PIPE_FORMAT_P016:
- texFormat = MESA_FORMAT_R_UNORM16;
- texObj->RequiredTextureImageUnits = 2;
- break;
- case PIPE_FORMAT_IYUV:
- texFormat = MESA_FORMAT_R_UNORM8;
- texObj->RequiredTextureImageUnits = 3;
- break;
- case PIPE_FORMAT_YUYV:
- case PIPE_FORMAT_UYVY:
- texFormat = MESA_FORMAT_RG_UNORM8;
- texObj->RequiredTextureImageUnits = 2;
- break;
- case PIPE_FORMAT_AYUV:
- texFormat = MESA_FORMAT_R8G8B8A8_UNORM;
- internalFormat = GL_RGBA;
- texObj->RequiredTextureImageUnits = 1;
- break;
- case PIPE_FORMAT_XYUV:
- texFormat = MESA_FORMAT_R8G8B8X8_UNORM;
- texObj->RequiredTextureImageUnits = 1;
- break;
- default:
+ if (!native_supported) {
+ switch (stimg->format) {
+ case PIPE_FORMAT_NV12:
+ texFormat = MESA_FORMAT_R_UNORM8;
+ texObj->RequiredTextureImageUnits = 2;
+ break;
+ case PIPE_FORMAT_P016:
+ texFormat = MESA_FORMAT_R_UNORM16;
+ texObj->RequiredTextureImageUnits = 2;
+ break;
+ case PIPE_FORMAT_IYUV:
+ texFormat = MESA_FORMAT_R_UNORM8;
+ texObj->RequiredTextureImageUnits = 3;
+ break;
+ case PIPE_FORMAT_YUYV:
+ case PIPE_FORMAT_UYVY:
+ texFormat = MESA_FORMAT_RG_UNORM8;
+ texObj->RequiredTextureImageUnits = 2;
+ break;
+ case PIPE_FORMAT_AYUV:
+ texFormat = MESA_FORMAT_R8G8B8A8_UNORM;
+ internalFormat = GL_RGBA;
+ texObj->RequiredTextureImageUnits = 1;
+ break;
+ case PIPE_FORMAT_XYUV:
+ texFormat = MESA_FORMAT_R8G8B8X8_UNORM;
+ texObj->RequiredTextureImageUnits = 1;
+ break;
+ default:
+ unreachable("unexpected emulated format");
+ break;
+ }
+ } else {
texFormat = st_pipe_format_to_mesa_format(stimg->format);
/* Use previously derived internalformat as specified by
* EXT_EGL_image_storage.
@@ -279,7 +289,6 @@ st_bind_egl_image(struct gl_context *ctx,
return;
}
}
- break;
}
assert(texFormat != MESA_FORMAT_NONE);
@@ -311,12 +320,14 @@ st_egl_image_target_texture_2d(struct gl_context *ctx, GLenum target,
GLeglImageOES image_handle)
{
struct st_egl_image stimg;
+ bool native_supported;
if (!st_get_egl_image(ctx, image_handle, PIPE_BIND_SAMPLER_VIEW,
- "glEGLImageTargetTexture2D", &stimg))
+ "glEGLImageTargetTexture2D", &stimg,
+ &native_supported))
return;
- st_bind_egl_image(ctx, texObj, texImage, &stimg, false);
+ st_bind_egl_image(ctx, texObj, texImage, &stimg, false, native_supported);
pipe_resource_reference(&stimg.texture, NULL);
}
@@ -327,12 +338,14 @@ st_egl_image_target_tex_storage(struct gl_context *ctx, GLenum target,
GLeglImageOES image_handle)
{
struct st_egl_image stimg;
+ bool native_supported;
if (!st_get_egl_image(ctx, image_handle, PIPE_BIND_SAMPLER_VIEW,
- "glEGLImageTargetTexture2D", &stimg))
+ "glEGLImageTargetTexture2D", &stimg,
+ &native_supported))
return;
- st_bind_egl_image(ctx, texObj, texImage, &stimg, true);
+ st_bind_egl_image(ctx, texObj, texImage, &stimg, true, native_supported);
pipe_resource_reference(&stimg.texture, NULL);
}
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index 69ad595143f..6b49f8d4681 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -71,8 +71,13 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog)
unsigned unit = u_bit_scan(&mask);
struct st_texture_object *stObj =
st_get_texture_object(st->ctx, prog, unit);
+ enum pipe_format format = st_get_view_format(stObj);
- switch (st_get_view_format(stObj)) {
+ /* if resource format matches then YUV wasn't lowered */
+ if (format == stObj->pt->format)
+ continue;
+
+ switch (format) {
case PIPE_FORMAT_NV12:
case PIPE_FORMAT_P010:
case PIPE_FORMAT_P016:
@@ -95,7 +100,7 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog)
break;
default:
printf("mesa: st_get_external_sampler_key: unhandled pipe format %u\n",
- st_get_view_format(stObj));
+ format);
break;
}
}
diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c
index 8c0277fe42a..102908e1029 100644
--- a/src/mesa/state_tracker/st_sampler_view.c
+++ b/src/mesa/state_tracker/st_sampler_view.c
@@ -489,6 +489,10 @@ get_sampler_view_format(struct st_context *st,
if (srgb_skip_decode)
format = util_format_linear(format);
+ /* if resource format matches then YUV wasn't lowered */
+ if (format == stObj->pt->format)
+ return format;
+
/* Use R8_UNORM for video formats */
switch (format) {
case PIPE_FORMAT_NV12: