summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/auxiliary/vl
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2016-12-11 08:40:05 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2016-12-11 08:40:05 +0000
commit21ab4c9f31674b113c24177398ed39f29b7cd8e6 (patch)
tree8be392d7a792d9663c2586396be77bfd506f5164 /lib/mesa/src/gallium/auxiliary/vl
parenta8f0a7916e26e550dd2a26e7188835c481978004 (diff)
Import Mesa 13.0.2
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/vl')
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_bicubic_filter.c459
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_bicubic_filter.h63
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_compositor.c269
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_compositor.h23
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_deint_filter.c9
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_idct.c14
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_matrix_filter.c6
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_mc.c8
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_median_filter.c11
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c28
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c2
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_rbsp.h20
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_video_buffer.c8
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_vlc.h8
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_winsys.h5
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_winsys_dri.c11
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_winsys_dri3.c763
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_winsys_drm.c12
-rw-r--r--lib/mesa/src/gallium/auxiliary/vl/vl_zscan.c9
19 files changed, 1576 insertions, 152 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_bicubic_filter.c b/lib/mesa/src/gallium/auxiliary/vl/vl_bicubic_filter.c
new file mode 100644
index 000000000..0364d4326
--- /dev/null
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_bicubic_filter.c
@@ -0,0 +1,459 @@
+/**************************************************************************
+ *
+ * Copyright 2016 Nayan Deshmukh.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+
+#include "pipe/p_context.h"
+
+#include "tgsi/tgsi_ureg.h"
+
+#include "util/u_draw.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_rect.h"
+
+#include "vl_types.h"
+#include "vl_vertex_buffers.h"
+#include "vl_bicubic_filter.h"
+
+enum VS_OUTPUT
+{
+ VS_O_VPOS = 0,
+ VS_O_VTEX = 0
+};
+
+static void *
+create_vert_shader(struct vl_bicubic_filter *filter)
+{
+ struct ureg_program *shader;
+ struct ureg_src i_vpos;
+ struct ureg_dst o_vpos, o_vtex;
+
+ shader = ureg_create(PIPE_SHADER_VERTEX);
+ if (!shader)
+ return NULL;
+
+ i_vpos = ureg_DECL_vs_input(shader, 0);
+ o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
+ o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX);
+
+ ureg_MOV(shader, o_vpos, i_vpos);
+ ureg_MOV(shader, o_vtex, i_vpos);
+
+ ureg_END(shader);
+
+ return ureg_create_shader_and_destroy(shader, filter->pipe);
+}
+
+static void
+create_frag_shader_cubic_interpolater(struct ureg_program *shader, struct ureg_src tex_a,
+ struct ureg_src tex_b, struct ureg_src tex_c,
+ struct ureg_src tex_d, struct ureg_src t,
+ struct ureg_dst o_fragment)
+{
+ struct ureg_dst temp[11];
+ struct ureg_dst t_2;
+ unsigned i;
+
+ for(i = 0; i < 11; ++i)
+ temp[i] = ureg_DECL_temporary(shader);
+ t_2 = ureg_DECL_temporary(shader);
+
+ /*
+ * |temp[0]| | 0 2 0 0 | |tex_a|
+ * |temp[1]| = | -1 0 1 0 |* |tex_b|
+ * |temp[2]| | 2 -5 4 -1 | |tex_c|
+ * |temp[3]| | -1 3 -3 1 | |tex_d|
+ */
+ ureg_MUL(shader, temp[0], tex_b, ureg_imm1f(shader, 2.0f));
+
+ ureg_MUL(shader, temp[1], tex_a, ureg_imm1f(shader, -1.0f));
+ ureg_MAD(shader, temp[1], tex_c, ureg_imm1f(shader, 1.0f),
+ ureg_src(temp[1]));
+
+ ureg_MUL(shader, temp[2], tex_a, ureg_imm1f(shader, 2.0f));
+ ureg_MAD(shader, temp[2], tex_b, ureg_imm1f(shader, -5.0f),
+ ureg_src(temp[2]));
+ ureg_MAD(shader, temp[2], tex_c, ureg_imm1f(shader, 4.0f),
+ ureg_src(temp[2]));
+ ureg_MAD(shader, temp[2], tex_d, ureg_imm1f(shader, -1.0f),
+ ureg_src(temp[2]));
+
+ ureg_MUL(shader, temp[3], tex_a, ureg_imm1f(shader, -1.0f));
+ ureg_MAD(shader, temp[3], tex_b, ureg_imm1f(shader, 3.0f),
+ ureg_src(temp[3]));
+ ureg_MAD(shader, temp[3], tex_c, ureg_imm1f(shader, -3.0f),
+ ureg_src(temp[3]));
+ ureg_MAD(shader, temp[3], tex_d, ureg_imm1f(shader, 1.0f),
+ ureg_src(temp[3]));
+
+ /*
+ * t_2 = t*t
+ * o_fragment = 0.5*|1 t t^2 t^3|*|temp[0]|
+ * |temp[1]|
+ * |temp[2]|
+ * |temp[3]|
+ */
+
+ ureg_MUL(shader, t_2, t, t);
+ ureg_MUL(shader, temp[4], ureg_src(t_2), t);
+
+ ureg_MUL(shader, temp[4], ureg_src(temp[4]),
+ ureg_src(temp[3]));
+ ureg_MUL(shader, temp[5], ureg_src(t_2),
+ ureg_src(temp[2]));
+ ureg_MUL(shader, temp[6], t,
+ ureg_src(temp[1]));
+ ureg_MUL(shader, temp[7], ureg_imm1f(shader, 1.0f),
+ ureg_src(temp[0]));
+ ureg_ADD(shader, temp[8], ureg_src(temp[4]),
+ ureg_src(temp[5]));
+ ureg_ADD(shader, temp[9], ureg_src(temp[6]),
+ ureg_src(temp[7]));
+
+ ureg_ADD(shader, temp[10], ureg_src(temp[8]),
+ ureg_src(temp[9]));
+ ureg_MUL(shader, o_fragment, ureg_src(temp[10]),
+ ureg_imm1f(shader, 0.5f));
+
+
+ for(i = 0; i < 11; ++i)
+ ureg_release_temporary(shader, temp[i]);
+ ureg_release_temporary(shader, t_2);
+}
+
+static void *
+create_frag_shader(struct vl_bicubic_filter *filter, unsigned video_width,
+ unsigned video_height, struct vertex2f *offsets)
+{
+ struct pipe_screen *screen = filter->pipe->screen;
+ struct ureg_program *shader;
+ struct ureg_src i_vtex, vtex;
+ struct ureg_src sampler;
+ struct ureg_src half_pixel;
+ struct ureg_dst t_array[23];
+ struct ureg_dst o_fragment;
+ struct ureg_dst t;
+ unsigned i;
+
+ if (screen->get_shader_param(
+ screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_TEMPS) < 23) {
+
+ return NULL;
+ }
+
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
+ if (!shader) {
+ return NULL;
+ }
+
+ i_vtex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);
+ sampler = ureg_DECL_sampler(shader, 0);
+
+ for (i = 0; i < 23; ++i)
+ t_array[i] = ureg_DECL_temporary(shader);
+ t = ureg_DECL_temporary(shader);
+
+ half_pixel = ureg_DECL_constant(shader, 0);
+ o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ /*
+ * temp = (i_vtex - (0.5/dst_size)) * i_size)
+ * t = frac(temp)
+ * vtex = floor(i_vtex)/i_size
+ */
+ ureg_SUB(shader, ureg_writemask(t_array[21], TGSI_WRITEMASK_XY),
+ i_vtex, half_pixel);
+ ureg_MUL(shader, ureg_writemask(t_array[22], TGSI_WRITEMASK_XY),
+ ureg_src(t_array[21]), ureg_imm2f(shader, video_width, video_height));
+ ureg_FRC(shader, ureg_writemask(t, TGSI_WRITEMASK_XY),
+ ureg_src(t_array[22]));
+
+ ureg_FLR(shader, ureg_writemask(t_array[22], TGSI_WRITEMASK_XY),
+ ureg_src(t_array[22]));
+ ureg_DIV(shader, ureg_writemask(t_array[22], TGSI_WRITEMASK_XY),
+ ureg_src(t_array[22]), ureg_imm2f(shader, video_width, video_height));
+ ureg_ADD(shader, ureg_writemask(t_array[22], TGSI_WRITEMASK_XY),
+ ureg_src(t_array[22]), half_pixel);
+
+ /*
+ * t_array[0..*] = vtex + offset[0..*]
+ * t_array[0..*] = tex(t_array[0..*], sampler)
+ * t_array[16+i] = cubic_interpolate(t_array[4*i..4*i+3], t_x)
+ * o_fragment = cubic_interpolate(t_array[16..19], t_y)
+ */
+ vtex = ureg_src(t_array[22]);
+ for (i = 0; i < 16; ++i) {
+ ureg_ADD(shader, ureg_writemask(t_array[i], TGSI_WRITEMASK_XY),
+ vtex, ureg_imm2f(shader, offsets[i].x, offsets[i].y));
+ ureg_MOV(shader, ureg_writemask(t_array[i], TGSI_WRITEMASK_ZW),
+ ureg_imm1f(shader, 0.0f));
+ }
+
+ for (i = 0; i < 16; ++i) {
+ ureg_TEX(shader, t_array[i], TGSI_TEXTURE_2D, ureg_src(t_array[i]), sampler);
+ }
+
+ for(i = 0; i < 4; ++i)
+ create_frag_shader_cubic_interpolater(shader, ureg_src(t_array[4*i]),
+ ureg_src(t_array[4*i+1]), ureg_src(t_array[4*i+2]), ureg_src(t_array[4*i+3]),
+ ureg_scalar(ureg_src(t), TGSI_SWIZZLE_X), t_array[16+i]);
+
+ create_frag_shader_cubic_interpolater(shader, ureg_src(t_array[16]),
+ ureg_src(t_array[17]), ureg_src(t_array[18]), ureg_src(t_array[19]),
+ ureg_scalar(ureg_src(t), TGSI_SWIZZLE_Y), o_fragment);
+
+ for(i = 0; i < 23; ++i)
+ ureg_release_temporary(shader, t_array[i]);
+ ureg_release_temporary(shader, t);
+
+ ureg_END(shader);
+
+ return ureg_create_shader_and_destroy(shader, filter->pipe);
+}
+
+bool
+vl_bicubic_filter_init(struct vl_bicubic_filter *filter, struct pipe_context *pipe,
+ unsigned width, unsigned height)
+{
+ struct pipe_rasterizer_state rs_state;
+ struct pipe_blend_state blend;
+ struct vertex2f offsets[16];
+ struct pipe_sampler_state sampler;
+ struct pipe_vertex_element ve;
+ unsigned i;
+
+ assert(filter && pipe);
+ assert(width && height);
+
+ memset(filter, 0, sizeof(*filter));
+ filter->pipe = pipe;
+
+ memset(&rs_state, 0, sizeof(rs_state));
+ rs_state.half_pixel_center = true;
+ rs_state.bottom_edge_rule = true;
+ rs_state.depth_clip = 1;
+ filter->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
+ if (!filter->rs_state)
+ goto error_rs_state;
+
+ memset(&blend, 0, sizeof blend);
+ blend.rt[0].rgb_func = PIPE_BLEND_ADD;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_func = PIPE_BLEND_ADD;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend.logicop_func = PIPE_LOGICOP_CLEAR;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
+ filter->blend = pipe->create_blend_state(pipe, &blend);
+ if (!filter->blend)
+ goto error_blend;
+
+ memset(&sampler, 0, sizeof(sampler));
+ sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
+ sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
+ sampler.compare_func = PIPE_FUNC_ALWAYS;
+ sampler.normalized_coords = 1;
+ filter->sampler = pipe->create_sampler_state(pipe, &sampler);
+ if (!filter->sampler)
+ goto error_sampler;
+
+ filter->quad = vl_vb_upload_quads(pipe);
+ if(!filter->quad.buffer)
+ goto error_quad;
+
+ memset(&ve, 0, sizeof(ve));
+ ve.src_offset = 0;
+ ve.instance_divisor = 0;
+ ve.vertex_buffer_index = 0;
+ ve.src_format = PIPE_FORMAT_R32G32_FLOAT;
+ filter->ves = pipe->create_vertex_elements_state(pipe, 1, &ve);
+ if (!filter->ves)
+ goto error_ves;
+
+ offsets[0].x = -1.0f; offsets[0].y = -1.0f;
+ offsets[1].x = 0.0f; offsets[1].y = -1.0f;
+ offsets[2].x = 1.0f; offsets[2].y = -1.0f;
+ offsets[3].x = 2.0f; offsets[3].y = -1.0f;
+
+ offsets[4].x = -1.0f; offsets[4].y = 0.0f;
+ offsets[5].x = 0.0f; offsets[5].y = 0.0f;
+ offsets[6].x = 1.0f; offsets[6].y = 0.0f;
+ offsets[7].x = 2.0f; offsets[7].y = 0.0f;
+
+ offsets[8].x = -1.0f; offsets[8].y = 1.0f;
+ offsets[9].x = 0.0f; offsets[9].y = 1.0f;
+ offsets[10].x = 1.0f; offsets[10].y = 1.0f;
+ offsets[11].x = 2.0f; offsets[11].y = 1.0f;
+
+ offsets[12].x = -1.0f; offsets[12].y = 2.0f;
+ offsets[13].x = 0.0f; offsets[13].y = 2.0f;
+ offsets[14].x = 1.0f; offsets[14].y = 2.0f;
+ offsets[15].x = 2.0f; offsets[15].y = 2.0f;
+
+ for (i = 0; i < 16; ++i) {
+ offsets[i].x /= width;
+ offsets[i].y /= height;
+ }
+
+ filter->vs = create_vert_shader(filter);
+ if (!filter->vs)
+ goto error_vs;
+
+ filter->fs = create_frag_shader(filter, width, height, offsets);
+ if (!filter->fs)
+ goto error_fs;
+
+ return true;
+
+error_fs:
+ pipe->delete_vs_state(pipe, filter->vs);
+
+error_vs:
+ pipe->delete_vertex_elements_state(pipe, filter->ves);
+
+error_ves:
+ pipe_resource_reference(&filter->quad.buffer, NULL);
+
+error_quad:
+ pipe->delete_sampler_state(pipe, filter->sampler);
+
+error_sampler:
+ pipe->delete_blend_state(pipe, filter->blend);
+
+error_blend:
+ pipe->delete_rasterizer_state(pipe, filter->rs_state);
+
+error_rs_state:
+ return false;
+}
+
+void
+vl_bicubic_filter_cleanup(struct vl_bicubic_filter *filter)
+{
+ assert(filter);
+
+ filter->pipe->delete_sampler_state(filter->pipe, filter->sampler);
+ filter->pipe->delete_blend_state(filter->pipe, filter->blend);
+ filter->pipe->delete_rasterizer_state(filter->pipe, filter->rs_state);
+ filter->pipe->delete_vertex_elements_state(filter->pipe, filter->ves);
+ pipe_resource_reference(&filter->quad.buffer, NULL);
+
+ filter->pipe->delete_vs_state(filter->pipe, filter->vs);
+ filter->pipe->delete_fs_state(filter->pipe, filter->fs);
+}
+
+void
+vl_bicubic_filter_render(struct vl_bicubic_filter *filter,
+ struct pipe_sampler_view *src,
+ struct pipe_surface *dst,
+ struct u_rect *dst_area,
+ struct u_rect *dst_clip)
+{
+ struct pipe_viewport_state viewport;
+ struct pipe_framebuffer_state fb_state;
+ struct pipe_scissor_state scissor;
+ union pipe_color_union clear_color;
+ struct pipe_transfer *buf_transfer;
+ struct pipe_resource *surface_size;
+ assert(filter && src && dst);
+
+ if (dst_clip) {
+ scissor.minx = dst_clip->x0;
+ scissor.miny = dst_clip->y0;
+ scissor.maxx = dst_clip->x1;
+ scissor.maxy = dst_clip->y1;
+ } else {
+ scissor.minx = 0;
+ scissor.miny = 0;
+ scissor.maxx = dst->width;
+ scissor.maxy = dst->height;
+ }
+
+ clear_color.f[0] = clear_color.f[1] = 0.0f;
+ clear_color.f[2] = clear_color.f[3] = 0.0f;
+ surface_size = pipe_buffer_create
+ (
+ filter->pipe->screen,
+ PIPE_BIND_CONSTANT_BUFFER,
+ PIPE_USAGE_DEFAULT,
+ 2*sizeof(float)
+ );
+
+
+ memset(&viewport, 0, sizeof(viewport));
+ if(dst_area){
+ viewport.scale[0] = dst_area->x1 - dst_area->x0;
+ viewport.scale[1] = dst_area->y1 - dst_area->y0;
+ viewport.translate[0] = dst_area->x0;
+ viewport.translate[1] = dst_area->y0;
+ } else {
+ viewport.scale[0] = dst->width;
+ viewport.scale[1] = dst->height;
+ }
+ viewport.scale[2] = 1;
+
+ float *ptr = pipe_buffer_map(filter->pipe, surface_size,
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
+ &buf_transfer);
+
+ ptr[0] = 0.5f/viewport.scale[0];
+ ptr[1] = 0.5f/viewport.scale[1];
+
+ pipe_buffer_unmap(filter->pipe, buf_transfer);
+
+ memset(&fb_state, 0, sizeof(fb_state));
+ fb_state.width = dst->width;
+ fb_state.height = dst->height;
+ fb_state.nr_cbufs = 1;
+ fb_state.cbufs[0] = dst;
+
+ filter->pipe->set_scissor_states(filter->pipe, 0, 1, &scissor);
+ filter->pipe->clear_render_target(filter->pipe, dst, &clear_color,
+ 0, 0, dst->width, dst->height, false);
+ pipe_set_constant_buffer(filter->pipe, PIPE_SHADER_FRAGMENT, 0, surface_size);
+ filter->pipe->bind_rasterizer_state(filter->pipe, filter->rs_state);
+ filter->pipe->bind_blend_state(filter->pipe, filter->blend);
+ filter->pipe->bind_sampler_states(filter->pipe, PIPE_SHADER_FRAGMENT,
+ 0, 1, &filter->sampler);
+ filter->pipe->set_sampler_views(filter->pipe, PIPE_SHADER_FRAGMENT,
+ 0, 1, &src);
+ filter->pipe->bind_vs_state(filter->pipe, filter->vs);
+ filter->pipe->bind_fs_state(filter->pipe, filter->fs);
+ filter->pipe->set_framebuffer_state(filter->pipe, &fb_state);
+ filter->pipe->set_viewport_states(filter->pipe, 0, 1, &viewport);
+ filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad);
+ filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves);
+
+ util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4);
+}
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_bicubic_filter.h b/lib/mesa/src/gallium/auxiliary/vl/vl_bicubic_filter.h
new file mode 100644
index 000000000..e5bef474e
--- /dev/null
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_bicubic_filter.h
@@ -0,0 +1,63 @@
+/**************************************************************************
+ *
+ * Copyright 2016 Nayan Deshmukh.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* implementation of bicubic interpolation filters */
+
+#ifndef vl_bicubic_filter_h
+#define vl_bicubic_filter_h
+
+#include "pipe/p_state.h"
+
+struct vl_bicubic_filter
+{
+ struct pipe_context *pipe;
+ struct pipe_vertex_buffer quad;
+
+ void *rs_state;
+ void *blend;
+ void *sampler;
+ void *ves;
+ void *vs, *fs;
+};
+
+bool
+vl_bicubic_filter_init(struct vl_bicubic_filter *filter, struct pipe_context *pipe,
+ unsigned width, unsigned height);
+
+void
+vl_bicubic_filter_cleanup(struct vl_bicubic_filter *filter);
+
+
+void
+vl_bicubic_filter_render(struct vl_bicubic_filter *filter,
+ struct pipe_sampler_view *src,
+ struct pipe_surface *dst,
+ struct u_rect *dst_area,
+ struct u_rect *dst_clip);
+
+
+#endif /* vl_bicubic_filter_h */
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_compositor.c b/lib/mesa/src/gallium/auxiliary/vl/vl_compositor.c
index 77688f0f9..03a0a6453 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_compositor.c
@@ -62,7 +62,7 @@ create_vert_shader(struct vl_compositor *c)
struct ureg_dst o_vpos, o_vtex, o_color;
struct ureg_dst o_vtop, o_vbottom;
- shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ shader = ureg_create(PIPE_SHADER_VERTEX);
if (!shader)
return false;
@@ -125,78 +125,25 @@ create_vert_shader(struct vl_compositor *c)
return ureg_create_shader_and_destroy(shader, c->pipe);
}
-static void *
-create_frag_shader_video_buffer(struct vl_compositor *c)
-{
- struct ureg_program *shader;
- struct ureg_src tc;
- struct ureg_src csc[3];
- struct ureg_src sampler[3];
- struct ureg_dst texel;
- struct ureg_dst fragment;
- unsigned i;
-
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
- if (!shader)
- return false;
-
- tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);
- for (i = 0; i < 3; ++i) {
- csc[i] = ureg_DECL_constant(shader, i);
- sampler[i] = ureg_DECL_sampler(shader, i);
- }
- texel = ureg_DECL_temporary(shader);
- fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
-
- /*
- * texel.xyz = tex(tc, sampler[i])
- * fragment = csc * texel
- */
- for (i = 0; i < 3; ++i)
- ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D_ARRAY, tc, sampler[i]);
-
- ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));
-
- for (i = 0; i < 3; ++i)
- ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i], ureg_src(texel));
-
- ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));
-
- ureg_release_temporary(shader, texel);
- ureg_END(shader);
-
- return ureg_create_shader_and_destroy(shader, c->pipe);
-}
-
-static void *
-create_frag_shader_weave(struct vl_compositor *c)
+static void
+create_frag_shader_weave(struct ureg_program *shader, struct ureg_dst fragment)
{
- struct ureg_program *shader;
struct ureg_src i_tc[2];
- struct ureg_src csc[3];
struct ureg_src sampler[3];
struct ureg_dst t_tc[2];
struct ureg_dst t_texel[2];
- struct ureg_dst o_fragment;
unsigned i, j;
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
- if (!shader)
- return false;
-
i_tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR);
i_tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR);
- for (i = 0; i < 3; ++i) {
- csc[i] = ureg_DECL_constant(shader, i);
+ for (i = 0; i < 3; ++i)
sampler[i] = ureg_DECL_sampler(shader, i);
- }
for (i = 0; i < 2; ++i) {
t_tc[i] = ureg_DECL_temporary(shader);
t_texel[i] = ureg_DECL_temporary(shader);
}
- o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
/* calculate the texture offsets
* t_tc.x = i_tc.x
@@ -239,23 +186,135 @@ create_frag_shader_weave(struct vl_compositor *c)
ureg_src(t_tc[0]), ureg_negate(i_tc[0]));
ureg_MUL(shader, ureg_writemask(t_tc[0], TGSI_WRITEMASK_YZ),
ureg_abs(ureg_src(t_tc[0])), ureg_imm1f(shader, 2.0f));
- ureg_LRP(shader, t_texel[0], ureg_swizzle(ureg_src(t_tc[0]),
+ ureg_LRP(shader, fragment, ureg_swizzle(ureg_src(t_tc[0]),
TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z),
ureg_src(t_texel[0]), ureg_src(t_texel[1]));
- /* and finally do colour space transformation
+ for (i = 0; i < 2; ++i) {
+ ureg_release_temporary(shader, t_texel[i]);
+ ureg_release_temporary(shader, t_tc[i]);
+ }
+}
+
+static void
+create_frag_shader_csc(struct ureg_program *shader, struct ureg_dst texel,
+ struct ureg_dst fragment)
+{
+ struct ureg_src csc[3];
+ struct ureg_src lumakey;
+ struct ureg_dst temp[2];
+ unsigned i;
+
+ for (i = 0; i < 3; ++i)
+ csc[i] = ureg_DECL_constant(shader, i);
+
+ lumakey = ureg_DECL_constant(shader, 3);
+
+ for (i = 0; i < 2; ++i)
+ temp[i] = ureg_DECL_temporary(shader);
+
+ ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_W),
+ ureg_imm1f(shader, 1.0f));
+
+ for (i = 0; i < 3; ++i)
+ ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i],
+ ureg_src(texel));
+
+ ureg_MOV(shader, ureg_writemask(temp[0], TGSI_WRITEMASK_W),
+ ureg_scalar(ureg_src(texel), TGSI_SWIZZLE_Z));
+ ureg_SLE(shader, ureg_writemask(temp[1],TGSI_WRITEMASK_W),
+ ureg_src(temp[0]), ureg_scalar(lumakey, TGSI_SWIZZLE_X));
+ ureg_SGT(shader, ureg_writemask(temp[0],TGSI_WRITEMASK_W),
+ ureg_src(temp[0]), ureg_scalar(lumakey, TGSI_SWIZZLE_Y));
+ ureg_MAX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W),
+ ureg_src(temp[0]), ureg_src(temp[1]));
+
+ for (i = 0; i < 2; ++i)
+ ureg_release_temporary(shader, temp[i]);
+}
+
+static void *
+create_frag_shader_video_buffer(struct vl_compositor *c)
+{
+ struct ureg_program *shader;
+ struct ureg_src tc;
+ struct ureg_src sampler[3];
+ struct ureg_dst texel;
+ struct ureg_dst fragment;
+ unsigned i;
+
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
+ if (!shader)
+ return false;
+
+ tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);
+ for (i = 0; i < 3; ++i)
+ sampler[i] = ureg_DECL_sampler(shader, i);
+
+ texel = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ /*
+ * texel.xyz = tex(tc, sampler[i])
* fragment = csc * texel
*/
- ureg_MOV(shader, ureg_writemask(t_texel[0], TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));
for (i = 0; i < 3; ++i)
- ureg_DP4(shader, ureg_writemask(o_fragment, TGSI_WRITEMASK_X << i), csc[i], ureg_src(t_texel[0]));
+ ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D_ARRAY, tc, sampler[i]);
- ureg_MOV(shader, ureg_writemask(o_fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));
+ create_frag_shader_csc(shader, texel, fragment);
- for (i = 0; i < 2; ++i) {
- ureg_release_temporary(shader, t_texel[i]);
- ureg_release_temporary(shader, t_tc[i]);
- }
+ ureg_release_temporary(shader, texel);
+ ureg_END(shader);
+
+ return ureg_create_shader_and_destroy(shader, c->pipe);
+}
+
+static void *
+create_frag_shader_weave_rgb(struct vl_compositor *c)
+{
+ struct ureg_program *shader;
+ struct ureg_dst texel, fragment;
+
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
+ if (!shader)
+ return false;
+
+ texel = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ create_frag_shader_weave(shader, texel);
+ create_frag_shader_csc(shader, texel, fragment);
+
+ ureg_release_temporary(shader, texel);
+
+ ureg_END(shader);
+
+ return ureg_create_shader_and_destroy(shader, c->pipe);
+}
+
+static void *
+create_frag_shader_weave_yuv(struct vl_compositor *c, bool y)
+{
+ struct ureg_program *shader;
+ struct ureg_dst texel, fragment;
+
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
+ if (!shader)
+ return false;
+
+ texel = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ create_frag_shader_weave(shader, texel);
+
+ if (y)
+ ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X), ureg_src(texel));
+ else
+ ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XY),
+ ureg_swizzle(ureg_src(texel), TGSI_SWIZZLE_Y,
+ TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W, TGSI_SWIZZLE_W));
+
+ ureg_release_temporary(shader, texel);
ureg_END(shader);
@@ -274,7 +333,7 @@ create_frag_shader_palette(struct vl_compositor *c, bool include_cc)
struct ureg_dst fragment;
unsigned i;
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader)
return false;
@@ -318,7 +377,7 @@ create_frag_shader_rgba(struct vl_compositor *c)
struct ureg_src tc, color, sampler;
struct ureg_dst texel, fragment;
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader)
return false;
@@ -355,12 +414,19 @@ init_shaders(struct vl_compositor *c)
return false;
}
- c->fs_weave = create_frag_shader_weave(c);
- if (!c->fs_weave) {
+ c->fs_weave_rgb = create_frag_shader_weave_rgb(c);
+ if (!c->fs_weave_rgb) {
debug_printf("Unable to create YCbCr-to-RGB weave fragment shader.\n");
return false;
}
+ c->fs_weave_yuv.y = create_frag_shader_weave_yuv(c, true);
+ c->fs_weave_yuv.uv = create_frag_shader_weave_yuv(c, false);
+ if (!c->fs_weave_yuv.y || !c->fs_weave_yuv.uv) {
+ debug_printf("Unable to create YCbCr i-to-YCbCr p weave fragment shader.\n");
+ return false;
+ }
+
c->fs_palette.yuv = create_frag_shader_palette(c, true);
if (!c->fs_palette.yuv) {
debug_printf("Unable to create YUV-Palette-to-RGB fragment shader.\n");
@@ -388,7 +454,9 @@ static void cleanup_shaders(struct vl_compositor *c)
c->pipe->delete_vs_state(c->pipe, c->vs);
c->pipe->delete_fs_state(c->pipe, c->fs_video_buffer);
- c->pipe->delete_fs_state(c->pipe, c->fs_weave);
+ c->pipe->delete_fs_state(c->pipe, c->fs_weave_rgb);
+ c->pipe->delete_fs_state(c->pipe, c->fs_weave_yuv.y);
+ c->pipe->delete_fs_state(c->pipe, c->fs_weave_yuv.uv);
c->pipe->delete_fs_state(c->pipe, c->fs_palette.yuv);
c->pipe->delete_fs_state(c->pipe, c->fs_palette.rgb);
c->pipe->delete_fs_state(c->pipe, c->fs_rgba);
@@ -852,20 +920,23 @@ vl_compositor_cleanup(struct vl_compositor *c)
}
void
-vl_compositor_set_csc_matrix(struct vl_compositor_state *s, vl_csc_matrix const *matrix)
+vl_compositor_set_csc_matrix(struct vl_compositor_state *s,
+ vl_csc_matrix const *matrix,
+ float luma_min, float luma_max)
{
struct pipe_transfer *buf_transfer;
assert(s);
- memcpy
- (
- pipe_buffer_map(s->pipe, s->csc_matrix,
- PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
- &buf_transfer),
- matrix,
- sizeof(vl_csc_matrix)
- );
+ float *ptr = pipe_buffer_map(s->pipe, s->csc_matrix,
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE,
+ &buf_transfer);
+
+ memcpy(ptr, matrix, sizeof(vl_csc_matrix));
+
+ ptr += sizeof(vl_csc_matrix)/sizeof(float);
+ ptr[0] = luma_min;
+ ptr[1] = luma_max;
pipe_buffer_unmap(s->pipe, buf_transfer);
}
@@ -945,7 +1016,7 @@ vl_compositor_set_buffer_layer(struct vl_compositor_state *s,
float half_a_line = 0.5f / s->layers[layer].zw.y;
switch(deinterlace) {
case VL_COMPOSITOR_WEAVE:
- s->layers[layer].fs = c->fs_weave;
+ s->layers[layer].fs = c->fs_weave_rgb;
break;
case VL_COMPOSITOR_BOB_TOP:
@@ -1040,6 +1111,36 @@ vl_compositor_set_layer_rotation(struct vl_compositor_state *s,
}
void
+vl_compositor_set_yuv_layer(struct vl_compositor_state *s,
+ struct vl_compositor *c,
+ unsigned layer,
+ struct pipe_video_buffer *buffer,
+ struct u_rect *src_rect,
+ struct u_rect *dst_rect,
+ bool y)
+{
+ struct pipe_sampler_view **sampler_views;
+ unsigned i;
+
+ assert(s && c && buffer);
+
+ assert(layer < VL_COMPOSITOR_MAX_LAYERS);
+
+ s->used_layers |= 1 << layer;
+ sampler_views = buffer->get_sampler_view_components(buffer);
+ for (i = 0; i < 3; ++i) {
+ s->layers[layer].samplers[i] = c->sampler_linear;
+ pipe_sampler_view_reference(&s->layers[layer].sampler_views[i], sampler_views[i]);
+ }
+
+ calc_src_and_dst(&s->layers[layer], buffer->width, buffer->height,
+ src_rect ? *src_rect : default_rect(&s->layers[layer]),
+ dst_rect ? *dst_rect : default_rect(&s->layers[layer]));
+
+ s->layers[layer].fs = (y) ? c->fs_weave_yuv.y : c->fs_weave_yuv.uv;
+}
+
+void
vl_compositor_render(struct vl_compositor_state *s,
struct vl_compositor *c,
struct pipe_surface *dst_surface,
@@ -1067,7 +1168,7 @@ vl_compositor_render(struct vl_compositor_state *s,
(dirty_area->x0 < dirty_area->x1 || dirty_area->y0 < dirty_area->y1)) {
c->pipe->clear_render_target(c->pipe, dst_surface, &s->clear_color,
- 0, 0, dst_surface->width, dst_surface->height);
+ 0, 0, dst_surface->width, dst_surface->height, false);
dirty_area->x0 = dirty_area->y0 = MAX_DIRTY;
dirty_area->x1 = dirty_area->y1 = MIN_DIRTY;
}
@@ -1142,13 +1243,13 @@ vl_compositor_init_state(struct vl_compositor_state *s, struct pipe_context *pip
pipe->screen,
PIPE_BIND_CONSTANT_BUFFER,
PIPE_USAGE_DEFAULT,
- sizeof(csc_matrix)
+ sizeof(csc_matrix) + 2*sizeof(float)
);
vl_compositor_clear_layers(s);
vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, &csc_matrix);
- vl_compositor_set_csc_matrix(s, (const vl_csc_matrix *)&csc_matrix);
+ vl_compositor_set_csc_matrix(s, (const vl_csc_matrix *)&csc_matrix, 1.0f, 0.0f);
return true;
}
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_compositor.h b/lib/mesa/src/gallium/auxiliary/vl/vl_compositor.h
index 934b634b3..ceab5e004 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_compositor.h
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_compositor.h
@@ -113,10 +113,15 @@ struct vl_compositor
void *vs;
void *fs_video_buffer;
- void *fs_weave;
+ void *fs_weave_rgb;
void *fs_rgba;
struct {
+ void *y;
+ void *uv;
+ } fs_weave_yuv;
+
+ struct {
void *rgb;
void *yuv;
} fs_palette;
@@ -138,7 +143,9 @@ vl_compositor_init_state(struct vl_compositor_state *state, struct pipe_context
* set yuv -> rgba conversion matrix
*/
void
-vl_compositor_set_csc_matrix(struct vl_compositor_state *settings, const vl_csc_matrix *matrix);
+vl_compositor_set_csc_matrix(struct vl_compositor_state *settings,
+ const vl_csc_matrix *matrix,
+ float luma_min, float luma_max);
/**
* reset dirty area, so it's cleared with the clear colour
@@ -234,6 +241,18 @@ vl_compositor_set_layer_rotation(struct vl_compositor_state *state,
unsigned layer,
enum vl_compositor_rotation rotate);
+/**
+ * set a layer of y or uv to render
+ */
+void
+vl_compositor_set_yuv_layer(struct vl_compositor_state *s,
+ struct vl_compositor *c,
+ unsigned layer,
+ struct pipe_video_buffer *buffer,
+ struct u_rect *src_rect,
+ struct u_rect *dst_rect,
+ bool y);
+
/*@}*/
/**
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_deint_filter.c b/lib/mesa/src/gallium/auxiliary/vl/vl_deint_filter.c
index 9e782e531..3ca3b4954 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_deint_filter.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_deint_filter.c
@@ -67,7 +67,7 @@ create_vert_shader(struct vl_deint_filter *filter)
struct ureg_src i_vpos;
struct ureg_dst o_vpos, o_vtex;
- shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ shader = ureg_create(PIPE_SHADER_VERTEX);
if (!shader)
return NULL;
@@ -92,7 +92,7 @@ create_copy_frag_shader(struct vl_deint_filter *filter, unsigned field)
struct ureg_dst o_fragment;
struct ureg_dst t_tex;
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader) {
return NULL;
}
@@ -136,7 +136,7 @@ create_deint_frag_shader(struct vl_deint_filter *filter, unsigned field,
struct ureg_dst t_a, t_b;
struct ureg_dst t_weave, t_linear;
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader) {
return NULL;
}
@@ -447,7 +447,8 @@ vl_deint_filter_render(struct vl_deint_filter *filter,
struct pipe_sampler_view *sampler_views[4];
struct pipe_surface **dst_surfaces;
const unsigned *plane_order;
- int i, j;
+ int i;
+ unsigned j;
assert(filter && prevprev && prev && cur && next && field <= 1);
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_idct.c b/lib/mesa/src/gallium/auxiliary/vl/vl_idct.c
index 948a5a403..3e6f58124 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_idct.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_idct.c
@@ -148,7 +148,7 @@ create_mismatch_vert_shader(struct vl_idct *idct)
struct ureg_dst t_tex;
struct ureg_dst o_vpos, o_addr[2];
- shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ shader = ureg_create(PIPE_SHADER_VERTEX);
if (!shader)
return NULL;
@@ -200,7 +200,7 @@ create_mismatch_frag_shader(struct vl_idct *idct)
unsigned i;
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader)
return NULL;
@@ -264,7 +264,7 @@ create_stage1_vert_shader(struct vl_idct *idct)
struct ureg_dst t_tex, t_start;
struct ureg_dst o_vpos, o_l_addr[2], o_r_addr[2];
- shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ shader = ureg_create(PIPE_SHADER_VERTEX);
if (!shader)
return NULL;
@@ -321,15 +321,13 @@ static void *
create_stage1_frag_shader(struct vl_idct *idct)
{
struct ureg_program *shader;
-
struct ureg_src l_addr[2], r_addr[2];
-
struct ureg_dst l[4][2], r[2];
struct ureg_dst *fragment;
+ unsigned i;
+ int j;
- int i, j;
-
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader)
return NULL;
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_matrix_filter.c b/lib/mesa/src/gallium/auxiliary/vl/vl_matrix_filter.c
index 52ce45401..e331cb758 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_matrix_filter.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_matrix_filter.c
@@ -52,7 +52,7 @@ create_vert_shader(struct vl_matrix_filter *filter)
struct ureg_src i_vpos;
struct ureg_dst o_vpos, o_vtex;
- shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ shader = ureg_create(PIPE_SHADER_VERTEX);
if (!shader)
return NULL;
@@ -85,9 +85,9 @@ create_frag_shader(struct vl_matrix_filter *filter, unsigned num_offsets,
struct ureg_dst t_sum;
struct ureg_dst o_fragment;
bool first;
- int i;
+ unsigned i;
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader) {
FREE(t_array);
return NULL;
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_mc.c b/lib/mesa/src/gallium/auxiliary/vl/vl_mc.c
index eb703a904..a202fac54 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_mc.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_mc.c
@@ -112,7 +112,7 @@ create_ref_vert_shader(struct vl_mc *r)
struct ureg_dst o_vmv[2];
unsigned i;
- shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ shader = ureg_create(PIPE_SHADER_VERTEX);
if (!shader)
return NULL;
@@ -169,7 +169,7 @@ create_ref_frag_shader(struct vl_mc *r)
struct ureg_dst fragment;
unsigned label;
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader)
return NULL;
@@ -241,7 +241,7 @@ create_ycbcr_vert_shader(struct vl_mc *r, vl_mc_ycbcr_vert_shader vs_callback, v
unsigned label;
- shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ shader = ureg_create(PIPE_SHADER_VERTEX);
if (!shader)
return NULL;
@@ -320,7 +320,7 @@ create_ycbcr_frag_shader(struct vl_mc *r, float scale, bool invert,
struct ureg_dst fragment;
unsigned label;
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader)
return NULL;
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_median_filter.c b/lib/mesa/src/gallium/auxiliary/vl/vl_median_filter.c
index aa9a6b264..f7477b757 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_median_filter.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_median_filter.c
@@ -50,7 +50,7 @@ create_vert_shader(struct vl_median_filter *filter)
struct ureg_src i_vpos;
struct ureg_dst o_vpos, o_vtex;
- shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ shader = ureg_create(PIPE_SHADER_VERTEX);
if (!shader)
return NULL;
@@ -84,7 +84,7 @@ create_frag_shader(struct vl_median_filter *filter,
struct ureg_dst *t_array = MALLOC(sizeof(struct ureg_dst) * num_offsets);
struct ureg_dst o_fragment;
const unsigned median = num_offsets >> 1;
- int i, j;
+ unsigned i, j;
assert(num_offsets & 1); /* we need an odd number of offsets */
if (!(num_offsets & 1)) { /* yeah, we REALLY need an odd number of offsets!!! */
@@ -93,13 +93,13 @@ create_frag_shader(struct vl_median_filter *filter,
}
if (num_offsets > screen->get_shader_param(
- screen, TGSI_PROCESSOR_FRAGMENT, PIPE_SHADER_CAP_MAX_TEMPS)) {
+ screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_MAX_TEMPS)) {
FREE(t_array);
return NULL;
}
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader) {
FREE(t_array);
return NULL;
@@ -158,7 +158,8 @@ static void
generate_offsets(enum vl_median_filter_shape shape, unsigned size,
struct vertex2f **offsets, unsigned *num_offsets)
{
- int i = 0, half_size;
+ unsigned i = 0;
+ int half_size;
struct vertex2f v;
assert(offsets && num_offsets);
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c b/lib/mesa/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
index 52ce6c416..0e99d830d 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
@@ -583,12 +583,12 @@ init_dct_coeff_table(struct dct_coeff *dst, const struct dct_coeff_compressed *s
break;
}
- for(i=0; i<(1 << (17 - coeff.length)); ++i)
+ for(i = 0; i < (1u << (17 - coeff.length)); ++i)
dst[src->bitcode << 1 | i] = coeff;
if (has_sign) {
coeff.level = -coeff.level;
- for(; i<(1 << (18 - coeff.length)); ++i)
+ for(; i < (1u << (18 - coeff.length)); ++i)
dst[src->bitcode << 1 | i] = coeff;
}
}
@@ -597,18 +597,18 @@ init_dct_coeff_table(struct dct_coeff *dst, const struct dct_coeff_compressed *s
static inline void
init_tables()
{
- vl_vlc_init_table(tbl_B1, Elements(tbl_B1), macroblock_address_increment, Elements(macroblock_address_increment));
- vl_vlc_init_table(tbl_B2, Elements(tbl_B2), macroblock_type_i, Elements(macroblock_type_i));
- vl_vlc_init_table(tbl_B3, Elements(tbl_B3), macroblock_type_p, Elements(macroblock_type_p));
- vl_vlc_init_table(tbl_B4, Elements(tbl_B4), macroblock_type_b, Elements(macroblock_type_b));
- vl_vlc_init_table(tbl_B9, Elements(tbl_B9), coded_block_pattern, Elements(coded_block_pattern));
- vl_vlc_init_table(tbl_B10, Elements(tbl_B10), motion_code, Elements(motion_code));
- vl_vlc_init_table(tbl_B11, Elements(tbl_B11), dmvector, Elements(dmvector));
- vl_vlc_init_table(tbl_B12, Elements(tbl_B12), dct_dc_size_luminance, Elements(dct_dc_size_luminance));
- vl_vlc_init_table(tbl_B13, Elements(tbl_B13), dct_dc_size_chrominance, Elements(dct_dc_size_chrominance));
- init_dct_coeff_table(tbl_B14_DC, dct_coeff_tbl_zero, Elements(dct_coeff_tbl_zero), true);
- init_dct_coeff_table(tbl_B14_AC, dct_coeff_tbl_zero, Elements(dct_coeff_tbl_zero), false);
- init_dct_coeff_table(tbl_B15, dct_coeff_tbl_one, Elements(dct_coeff_tbl_one), false);
+ vl_vlc_init_table(tbl_B1, ARRAY_SIZE(tbl_B1), macroblock_address_increment, ARRAY_SIZE(macroblock_address_increment));
+ vl_vlc_init_table(tbl_B2, ARRAY_SIZE(tbl_B2), macroblock_type_i, ARRAY_SIZE(macroblock_type_i));
+ vl_vlc_init_table(tbl_B3, ARRAY_SIZE(tbl_B3), macroblock_type_p, ARRAY_SIZE(macroblock_type_p));
+ vl_vlc_init_table(tbl_B4, ARRAY_SIZE(tbl_B4), macroblock_type_b, ARRAY_SIZE(macroblock_type_b));
+ vl_vlc_init_table(tbl_B9, ARRAY_SIZE(tbl_B9), coded_block_pattern, ARRAY_SIZE(coded_block_pattern));
+ vl_vlc_init_table(tbl_B10, ARRAY_SIZE(tbl_B10), motion_code, ARRAY_SIZE(motion_code));
+ vl_vlc_init_table(tbl_B11, ARRAY_SIZE(tbl_B11), dmvector, ARRAY_SIZE(dmvector));
+ vl_vlc_init_table(tbl_B12, ARRAY_SIZE(tbl_B12), dct_dc_size_luminance, ARRAY_SIZE(dct_dc_size_luminance));
+ vl_vlc_init_table(tbl_B13, ARRAY_SIZE(tbl_B13), dct_dc_size_chrominance, ARRAY_SIZE(dct_dc_size_chrominance));
+ init_dct_coeff_table(tbl_B14_DC, dct_coeff_tbl_zero, ARRAY_SIZE(dct_coeff_tbl_zero), true);
+ init_dct_coeff_table(tbl_B14_AC, dct_coeff_tbl_zero, ARRAY_SIZE(dct_coeff_tbl_zero), false);
+ init_dct_coeff_table(tbl_B15, dct_coeff_tbl_one, ARRAY_SIZE(dct_coeff_tbl_one), false);
}
static inline int
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/lib/mesa/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
index b5c70451c..db62b44f5 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
@@ -189,7 +189,7 @@ init_zscan_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buffer
memset(&sv_tmpl, 0, sizeof(sv_tmpl));
u_sampler_view_default_template(&sv_tmpl, res, res->format);
- sv_tmpl.swizzle_r = sv_tmpl.swizzle_g = sv_tmpl.swizzle_b = sv_tmpl.swizzle_a = PIPE_SWIZZLE_RED;
+ sv_tmpl.swizzle_r = sv_tmpl.swizzle_g = sv_tmpl.swizzle_b = sv_tmpl.swizzle_a = PIPE_SWIZZLE_X;
buffer->zscan_source = dec->context->create_sampler_view(dec->context, res, &sv_tmpl);
pipe_resource_reference(&res, NULL);
if (!buffer->zscan_source)
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_rbsp.h b/lib/mesa/src/gallium/auxiliary/vl/vl_rbsp.h
index 7867238c4..4d90c2de0 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_rbsp.h
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_rbsp.h
@@ -50,22 +50,34 @@ struct vl_rbsp {
*/
static inline void vl_rbsp_init(struct vl_rbsp *rbsp, struct vl_vlc *nal, unsigned num_bits)
{
- unsigned bits_left = vl_vlc_bits_left(nal);
+ unsigned valid, bits_left = vl_vlc_bits_left(nal);
+ int i;
/* copy the position */
rbsp->nal = *nal;
- rbsp->escaped = 0;
-
/* search for the end of the NAL unit */
while (vl_vlc_search_byte(nal, num_bits, 0x00)) {
if (vl_vlc_peekbits(nal, 24) == 0x000001 ||
vl_vlc_peekbits(nal, 32) == 0x00000001) {
vl_vlc_limit(&rbsp->nal, bits_left - vl_vlc_bits_left(nal));
- return;
+ break;
}
vl_vlc_eatbits(nal, 8);
}
+
+ valid = vl_vlc_valid_bits(&rbsp->nal);
+ /* search for the emulation prevention three byte */
+ for (i = 24; i <= valid; i += 8) {
+ if ((vl_vlc_peekbits(&rbsp->nal, i) & 0xffffff) == 0x3) {
+ vl_vlc_removebits(&rbsp->nal, i - 8, 8);
+ i += 8;
+ }
+ }
+
+ valid = vl_vlc_valid_bits(&rbsp->nal);
+
+ rbsp->escaped = (valid >= 16) ? 16 : ((valid >= 8) ? 8 : 0);
}
/**
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_video_buffer.c b/lib/mesa/src/gallium/auxiliary/vl/vl_video_buffer.c
index 462fdcb08..fdc9598f8 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_video_buffer.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_video_buffer.c
@@ -250,7 +250,7 @@ vl_video_buffer_template(struct pipe_resource *templ,
templ->height0 = tmpl->height;
templ->depth0 = depth;
templ->array_size = array_size;
- templ->bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+ templ->bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET | tmpl->bind;
templ->usage = usage;
vl_video_buffer_adjust_size(&templ->width0, &templ->height0, plane,
@@ -297,7 +297,7 @@ vl_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format);
if (util_format_get_nr_components(buf->resources[i]->format) == 1)
- sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = sv_templ.swizzle_a = PIPE_SWIZZLE_RED;
+ sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = sv_templ.swizzle_a = PIPE_SWIZZLE_X;
buf->sampler_view_planes[i] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ);
if (!buf->sampler_view_planes[i])
@@ -344,8 +344,8 @@ vl_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
memset(&sv_templ, 0, sizeof(sv_templ));
u_sampler_view_default_template(&sv_templ, res, sampler_format[plane_order[i]]);
- sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
- sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
+ sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_X + j;
+ sv_templ.swizzle_a = PIPE_SWIZZLE_1;
buf->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
if (!buf->sampler_view_components[component])
goto error;
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_vlc.h b/lib/mesa/src/gallium/auxiliary/vl/vl_vlc.h
index 7821b8be0..dd7b0918a 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_vlc.h
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_vlc.h
@@ -79,7 +79,7 @@ vl_vlc_init_table(struct vl_vlc_entry *dst, unsigned dst_size, const struct vl_v
}
for(; src_size > 0; --src_size, ++src) {
- for(i=0; i<(1 << (bits - src->entry.length)); ++i)
+ for(i = 0; i < (1u << (bits - src->entry.length)); ++i)
dst[src->bitcode >> (16 - bits) | i] = src->entry;
}
}
@@ -293,7 +293,7 @@ vl_vlc_search_byte(struct vl_vlc *vlc, unsigned num_bits, uint8_t value)
{
/* make sure we are on a byte boundary */
assert((vl_vlc_valid_bits(vlc) % 8) == 0);
- assert(num_bits == ~0 || (num_bits % 8) == 0);
+ assert(num_bits == ~0u || (num_bits % 8) == 0);
/* deplete the bit buffer */
while (vl_vlc_valid_bits(vlc) > 0) {
@@ -305,7 +305,7 @@ vl_vlc_search_byte(struct vl_vlc *vlc, unsigned num_bits, uint8_t value)
vl_vlc_eatbits(vlc, 8);
- if (num_bits != ~0) {
+ if (num_bits != ~0u) {
num_bits -= 8;
if (num_bits == 0)
return FALSE;
@@ -332,7 +332,7 @@ vl_vlc_search_byte(struct vl_vlc *vlc, unsigned num_bits, uint8_t value)
}
++vlc->data;
- if (num_bits != ~0) {
+ if (num_bits != ~0u) {
num_bits -= 8;
if (num_bits == 0) {
vl_vlc_align_data_ptr(vlc);
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_winsys.h b/lib/mesa/src/gallium/auxiliary/vl/vl_winsys.h
index 1af7653d6..26db9f263 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_winsys.h
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_winsys.h
@@ -69,4 +69,9 @@ vl_dri2_screen_create(Display *display, int screen);
struct vl_screen *
vl_drm_screen_create(int fd);
+#if defined(HAVE_DRI3)
+struct vl_screen *
+vl_dri3_screen_create(Display *display, int screen);
+#endif
+
#endif
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_dri.c b/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_dri.c
index 758f50d7c..9ecc216b9 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_dri.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_dri.c
@@ -248,7 +248,8 @@ vl_dri2_screen_texture_from_drawable(struct vl_screen *vscreen, void *drawable)
template.flags = 0;
tex = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &template,
- &dri2_handle);
+ &dri2_handle,
+ PIPE_HANDLE_USAGE_READ_WRITE);
free(reply);
return tex;
@@ -426,13 +427,15 @@ vl_dri2_screen_create(Display *display, int screen)
return &scrn->base;
release_pipe:
- if (scrn->base.dev)
+ if (scrn->base.dev) {
pipe_loader_release(&scrn->base.dev, 1);
- fd = -1;
+ fd = -1;
+ }
free_authenticate:
free(authenticate);
close_fd:
- close(fd);
+ if (fd != -1)
+ close(fd);
free_connect:
free(connect);
free_query:
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_dri3.c b/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_dri3.c
new file mode 100644
index 000000000..29299289f
--- /dev/null
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_dri3.c
@@ -0,0 +1,763 @@
+/**************************************************************************
+ *
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <fcntl.h>
+
+#include <X11/Xlib-xcb.h>
+#include <X11/xshmfence.h>
+#include <xcb/dri3.h>
+#include <xcb/present.h>
+
+#include "loader.h"
+
+#include "pipe/p_screen.h"
+#include "pipe/p_state.h"
+#include "pipe-loader/pipe_loader.h"
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "vl/vl_compositor.h"
+#include "vl/vl_winsys.h"
+
+#define BACK_BUFFER_NUM 3
+
+struct vl_dri3_buffer
+{
+ struct pipe_resource *texture;
+ struct pipe_resource *linear_texture;
+
+ uint32_t pixmap;
+ uint32_t sync_fence;
+ struct xshmfence *shm_fence;
+
+ bool busy;
+ uint32_t width, height, pitch;
+};
+
+struct vl_dri3_screen
+{
+ struct vl_screen base;
+ xcb_connection_t *conn;
+ xcb_drawable_t drawable;
+
+ uint32_t width, height, depth;
+
+ xcb_present_event_t eid;
+ xcb_special_event_t *special_event;
+
+ struct pipe_context *pipe;
+
+ struct vl_dri3_buffer *back_buffers[BACK_BUFFER_NUM];
+ int cur_back;
+
+ struct u_rect dirty_areas[BACK_BUFFER_NUM];
+
+ struct vl_dri3_buffer *front_buffer;
+ bool is_pixmap;
+
+ uint32_t send_msc_serial, recv_msc_serial;
+ uint64_t send_sbc, recv_sbc;
+ int64_t last_ust, ns_frame, last_msc, next_msc;
+
+ bool flushed;
+ int is_different_gpu;
+};
+
+static void
+dri3_free_front_buffer(struct vl_dri3_screen *scrn,
+ struct vl_dri3_buffer *buffer)
+{
+ xcb_sync_destroy_fence(scrn->conn, buffer->sync_fence);
+ xshmfence_unmap_shm(buffer->shm_fence);
+ pipe_resource_reference(&buffer->texture, NULL);
+ FREE(buffer);
+}
+
+static void
+dri3_free_back_buffer(struct vl_dri3_screen *scrn,
+ struct vl_dri3_buffer *buffer)
+{
+ xcb_free_pixmap(scrn->conn, buffer->pixmap);
+ xcb_sync_destroy_fence(scrn->conn, buffer->sync_fence);
+ xshmfence_unmap_shm(buffer->shm_fence);
+ pipe_resource_reference(&buffer->texture, NULL);
+ if (buffer->linear_texture)
+ pipe_resource_reference(&buffer->linear_texture, NULL);
+ FREE(buffer);
+}
+
+static void
+dri3_handle_stamps(struct vl_dri3_screen *scrn, uint64_t ust, uint64_t msc)
+{
+ int64_t ust_ns = ust * 1000;
+
+ if (scrn->last_ust && (ust_ns > scrn->last_ust) &&
+ scrn->last_msc && (msc > scrn->last_msc))
+ scrn->ns_frame = (ust_ns - scrn->last_ust) / (msc - scrn->last_msc);
+
+ scrn->last_ust = ust_ns;
+ scrn->last_msc = msc;
+}
+
+static void
+dri3_handle_present_event(struct vl_dri3_screen *scrn,
+ xcb_present_generic_event_t *ge)
+{
+ switch (ge->evtype) {
+ case XCB_PRESENT_CONFIGURE_NOTIFY: {
+ xcb_present_configure_notify_event_t *ce = (void *) ge;
+ scrn->width = ce->width;
+ scrn->height = ce->height;
+ break;
+ }
+ case XCB_PRESENT_COMPLETE_NOTIFY: {
+ xcb_present_complete_notify_event_t *ce = (void *) ge;
+ if (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP) {
+ scrn->recv_sbc = (scrn->send_sbc & 0xffffffff00000000LL) | ce->serial;
+ if (scrn->recv_sbc > scrn->send_sbc)
+ scrn->recv_sbc -= 0x100000000;
+ dri3_handle_stamps(scrn, ce->ust, ce->msc);
+ } else if (ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC) {
+ scrn->recv_msc_serial = ce->serial;
+ dri3_handle_stamps(scrn, ce->ust, ce->msc);
+ }
+ break;
+ }
+ case XCB_PRESENT_EVENT_IDLE_NOTIFY: {
+ xcb_present_idle_notify_event_t *ie = (void *) ge;
+ int b;
+ for (b = 0; b < BACK_BUFFER_NUM; b++) {
+ struct vl_dri3_buffer *buf = scrn->back_buffers[b];
+ if (buf && buf->pixmap == ie->pixmap) {
+ buf->busy = false;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ free(ge);
+}
+
+static void
+dri3_flush_present_events(struct vl_dri3_screen *scrn)
+{
+ if (scrn->special_event) {
+ xcb_generic_event_t *ev;
+ while ((ev = xcb_poll_for_special_event(
+ scrn->conn, scrn->special_event)) != NULL)
+ dri3_handle_present_event(scrn, (xcb_present_generic_event_t *)ev);
+ }
+}
+
+static bool
+dri3_wait_present_events(struct vl_dri3_screen *scrn)
+{
+ if (scrn->special_event) {
+ xcb_generic_event_t *ev;
+ ev = xcb_wait_for_special_event(scrn->conn, scrn->special_event);
+ if (!ev)
+ return false;
+ dri3_handle_present_event(scrn, (xcb_present_generic_event_t *)ev);
+ return true;
+ }
+ return false;
+}
+
+static int
+dri3_find_back(struct vl_dri3_screen *scrn)
+{
+ int b;
+
+ for (;;) {
+ for (b = 0; b < BACK_BUFFER_NUM; b++) {
+ int id = (b + scrn->cur_back) % BACK_BUFFER_NUM;
+ struct vl_dri3_buffer *buffer = scrn->back_buffers[id];
+ if (!buffer || !buffer->busy)
+ return id;
+ }
+ xcb_flush(scrn->conn);
+ if (!dri3_wait_present_events(scrn))
+ return -1;
+ }
+}
+
+static struct vl_dri3_buffer *
+dri3_alloc_back_buffer(struct vl_dri3_screen *scrn)
+{
+ struct vl_dri3_buffer *buffer;
+ xcb_pixmap_t pixmap;
+ xcb_sync_fence_t sync_fence;
+ struct xshmfence *shm_fence;
+ int buffer_fd, fence_fd;
+ struct pipe_resource templ, *pixmap_buffer_texture;
+ struct winsys_handle whandle;
+ unsigned usage;
+
+ buffer = CALLOC_STRUCT(vl_dri3_buffer);
+ if (!buffer)
+ return NULL;
+
+ fence_fd = xshmfence_alloc_shm();
+ if (fence_fd < 0)
+ goto free_buffer;
+
+ shm_fence = xshmfence_map_shm(fence_fd);
+ if (!shm_fence)
+ goto close_fd;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ templ.format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = scrn->width;
+ templ.height0 = scrn->height;
+ templ.depth0 = 1;
+ templ.array_size = 1;
+
+ if (scrn->is_different_gpu) {
+ buffer->texture = scrn->base.pscreen->resource_create(scrn->base.pscreen,
+ &templ);
+ if (!buffer->texture)
+ goto unmap_shm;
+
+ templ.bind |= PIPE_BIND_SCANOUT | PIPE_BIND_SHARED |
+ PIPE_BIND_LINEAR;
+ buffer->linear_texture = scrn->base.pscreen->resource_create(scrn->base.pscreen,
+ &templ);
+ pixmap_buffer_texture = buffer->linear_texture;
+
+ if (!buffer->linear_texture)
+ goto no_linear_texture;
+ } else {
+ templ.bind |= PIPE_BIND_SCANOUT | PIPE_BIND_SHARED;
+ buffer->texture = scrn->base.pscreen->resource_create(scrn->base.pscreen,
+ &templ);
+ if (!buffer->texture)
+ goto unmap_shm;
+ pixmap_buffer_texture = buffer->texture;
+ }
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type= DRM_API_HANDLE_TYPE_FD;
+ usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ;
+ scrn->base.pscreen->resource_get_handle(scrn->base.pscreen, NULL,
+ pixmap_buffer_texture, &whandle,
+ usage);
+ buffer_fd = whandle.handle;
+ buffer->pitch = whandle.stride;
+ xcb_dri3_pixmap_from_buffer(scrn->conn,
+ (pixmap = xcb_generate_id(scrn->conn)),
+ scrn->drawable,
+ 0,
+ scrn->width, scrn->height, buffer->pitch,
+ scrn->depth, 32,
+ buffer_fd);
+ xcb_dri3_fence_from_fd(scrn->conn,
+ pixmap,
+ (sync_fence = xcb_generate_id(scrn->conn)),
+ false,
+ fence_fd);
+
+ buffer->pixmap = pixmap;
+ buffer->sync_fence = sync_fence;
+ buffer->shm_fence = shm_fence;
+ buffer->width = scrn->width;
+ buffer->height = scrn->height;
+
+ xshmfence_trigger(buffer->shm_fence);
+
+ return buffer;
+
+no_linear_texture:
+ pipe_resource_reference(&buffer->texture, NULL);
+unmap_shm:
+ xshmfence_unmap_shm(shm_fence);
+close_fd:
+ close(fence_fd);
+free_buffer:
+ FREE(buffer);
+ return NULL;
+}
+
+static struct vl_dri3_buffer *
+dri3_get_back_buffer(struct vl_dri3_screen *scrn)
+{
+ struct vl_dri3_buffer *buffer;
+ struct pipe_resource *texture = NULL;
+
+ assert(scrn);
+
+ scrn->cur_back = dri3_find_back(scrn);
+ if (scrn->cur_back < 0)
+ return NULL;
+ buffer = scrn->back_buffers[scrn->cur_back];
+
+ if (!buffer || buffer->width != scrn->width ||
+ buffer->height != scrn->height) {
+ struct vl_dri3_buffer *new_buffer;
+
+ new_buffer = dri3_alloc_back_buffer(scrn);
+ if (!new_buffer)
+ return NULL;
+
+ if (buffer)
+ dri3_free_back_buffer(scrn, buffer);
+
+ vl_compositor_reset_dirty_area(&scrn->dirty_areas[scrn->cur_back]);
+ buffer = new_buffer;
+ scrn->back_buffers[scrn->cur_back] = buffer;
+ }
+
+ pipe_resource_reference(&texture, buffer->texture);
+ xcb_flush(scrn->conn);
+ xshmfence_await(buffer->shm_fence);
+
+ return buffer;
+}
+
+static bool
+dri3_set_drawable(struct vl_dri3_screen *scrn, Drawable drawable)
+{
+ xcb_get_geometry_cookie_t geom_cookie;
+ xcb_get_geometry_reply_t *geom_reply;
+ xcb_void_cookie_t cookie;
+ xcb_generic_error_t *error;
+ bool ret = true;
+
+ assert(drawable);
+
+ if (scrn->drawable == drawable)
+ return true;
+
+ scrn->drawable = drawable;
+
+ geom_cookie = xcb_get_geometry(scrn->conn, scrn->drawable);
+ geom_reply = xcb_get_geometry_reply(scrn->conn, geom_cookie, NULL);
+ if (!geom_reply)
+ return false;
+
+ scrn->width = geom_reply->width;
+ scrn->height = geom_reply->height;
+ scrn->depth = geom_reply->depth;
+ free(geom_reply);
+
+ if (scrn->special_event) {
+ xcb_unregister_for_special_event(scrn->conn, scrn->special_event);
+ scrn->special_event = NULL;
+ cookie = xcb_present_select_input_checked(scrn->conn, scrn->eid,
+ scrn->drawable,
+ XCB_PRESENT_EVENT_MASK_NO_EVENT);
+ xcb_discard_reply(scrn->conn, cookie.sequence);
+ }
+
+ scrn->is_pixmap = false;
+ scrn->eid = xcb_generate_id(scrn->conn);
+ cookie =
+ xcb_present_select_input_checked(scrn->conn, scrn->eid, scrn->drawable,
+ XCB_PRESENT_EVENT_MASK_CONFIGURE_NOTIFY |
+ XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY |
+ XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY);
+
+ error = xcb_request_check(scrn->conn, cookie);
+ if (error) {
+ if (error->error_code != BadWindow)
+ ret = false;
+ else {
+ scrn->is_pixmap = true;
+ if (scrn->front_buffer) {
+ dri3_free_front_buffer(scrn, scrn->front_buffer);
+ scrn->front_buffer = NULL;
+ }
+ }
+ free(error);
+ } else
+ scrn->special_event =
+ xcb_register_for_special_xge(scrn->conn, &xcb_present_id, scrn->eid, 0);
+
+ dri3_flush_present_events(scrn);
+
+ return ret;
+}
+
+static struct vl_dri3_buffer *
+dri3_get_front_buffer(struct vl_dri3_screen *scrn)
+{
+ xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie;
+ xcb_dri3_buffer_from_pixmap_reply_t *bp_reply;
+ xcb_sync_fence_t sync_fence;
+ struct xshmfence *shm_fence;
+ int fence_fd, *fds;
+ struct winsys_handle whandle;
+ struct pipe_resource templ, *texture = NULL;
+
+ if (scrn->front_buffer) {
+ pipe_resource_reference(&texture, scrn->front_buffer->texture);
+ return scrn->front_buffer;
+ }
+
+ scrn->front_buffer = CALLOC_STRUCT(vl_dri3_buffer);
+ if (!scrn->front_buffer)
+ return NULL;
+
+ fence_fd = xshmfence_alloc_shm();
+ if (fence_fd < 0)
+ goto free_buffer;
+
+ shm_fence = xshmfence_map_shm(fence_fd);
+ if (!shm_fence)
+ goto close_fd;
+
+ bp_cookie = xcb_dri3_buffer_from_pixmap(scrn->conn, scrn->drawable);
+ bp_reply = xcb_dri3_buffer_from_pixmap_reply(scrn->conn, bp_cookie, NULL);
+ if (!bp_reply)
+ goto unmap_shm;
+
+ fds = xcb_dri3_buffer_from_pixmap_reply_fds(scrn->conn, bp_reply);
+ if (fds[0] < 0)
+ goto free_reply;
+
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_FD;
+ whandle.handle = (unsigned)fds[0];
+ whandle.stride = bp_reply->stride;
+ memset(&templ, 0, sizeof(templ));
+ templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ templ.format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = bp_reply->width;
+ templ.height0 = bp_reply->height;
+ templ.depth0 = 1;
+ templ.array_size = 1;
+ scrn->front_buffer->texture =
+ scrn->base.pscreen->resource_from_handle(scrn->base.pscreen,
+ &templ, &whandle,
+ PIPE_HANDLE_USAGE_READ_WRITE);
+ close(fds[0]);
+ if (!scrn->front_buffer->texture)
+ goto free_reply;
+
+ xcb_dri3_fence_from_fd(scrn->conn,
+ scrn->drawable,
+ (sync_fence = xcb_generate_id(scrn->conn)),
+ false,
+ fence_fd);
+
+ pipe_resource_reference(&texture, scrn->front_buffer->texture);
+ scrn->front_buffer->pixmap = scrn->drawable;
+ scrn->front_buffer->width = bp_reply->width;
+ scrn->front_buffer->height = bp_reply->height;
+ scrn->front_buffer->shm_fence = shm_fence;
+ scrn->front_buffer->sync_fence = sync_fence;
+ free(bp_reply);
+
+ return scrn->front_buffer;
+
+free_reply:
+ free(bp_reply);
+unmap_shm:
+ xshmfence_unmap_shm(shm_fence);
+close_fd:
+ close(fence_fd);
+free_buffer:
+ FREE(scrn->front_buffer);
+ return NULL;
+}
+
+static void
+vl_dri3_flush_frontbuffer(struct pipe_screen *screen,
+ struct pipe_resource *resource,
+ unsigned level, unsigned layer,
+ void *context_private, struct pipe_box *sub_box)
+{
+ struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)context_private;
+ uint32_t options = XCB_PRESENT_OPTION_NONE;
+ struct vl_dri3_buffer *back;
+ struct pipe_box src_box;
+
+ back = scrn->back_buffers[scrn->cur_back];
+ if (!back)
+ return;
+
+ if (scrn->flushed) {
+ while (scrn->special_event && scrn->recv_sbc < scrn->send_sbc)
+ if (!dri3_wait_present_events(scrn))
+ return;
+ }
+
+ if (scrn->is_different_gpu) {
+ u_box_origin_2d(scrn->width, scrn->height, &src_box);
+ scrn->pipe->resource_copy_region(scrn->pipe,
+ back->linear_texture,
+ 0, 0, 0, 0,
+ back->texture,
+ 0, &src_box);
+
+ scrn->pipe->flush(scrn->pipe, NULL, 0);
+ }
+ xshmfence_reset(back->shm_fence);
+ back->busy = true;
+
+ xcb_present_pixmap(scrn->conn,
+ scrn->drawable,
+ back->pixmap,
+ (uint32_t)(++scrn->send_sbc),
+ 0, 0, 0, 0,
+ None, None,
+ back->sync_fence,
+ options,
+ scrn->next_msc,
+ 0, 0, 0, NULL);
+
+ xcb_flush(scrn->conn);
+
+ scrn->flushed = true;
+
+ return;
+}
+
+static struct pipe_resource *
+vl_dri3_screen_texture_from_drawable(struct vl_screen *vscreen, void *drawable)
+{
+ struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen;
+ struct vl_dri3_buffer *buffer;
+
+ assert(scrn);
+
+ if (!dri3_set_drawable(scrn, (Drawable)drawable))
+ return NULL;
+
+ if (scrn->flushed) {
+ while (scrn->special_event && scrn->recv_sbc < scrn->send_sbc)
+ if (!dri3_wait_present_events(scrn))
+ return NULL;
+ }
+ scrn->flushed = false;
+
+ buffer = (scrn->is_pixmap) ?
+ dri3_get_front_buffer(scrn) :
+ dri3_get_back_buffer(scrn);
+ if (!buffer)
+ return NULL;
+
+ return buffer->texture;
+}
+
+static struct u_rect *
+vl_dri3_screen_get_dirty_area(struct vl_screen *vscreen)
+{
+ struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen;
+
+ assert(scrn);
+
+ return &scrn->dirty_areas[scrn->cur_back];
+}
+
+static uint64_t
+vl_dri3_screen_get_timestamp(struct vl_screen *vscreen, void *drawable)
+{
+ struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen;
+
+ assert(scrn);
+
+ if (!dri3_set_drawable(scrn, (Drawable)drawable))
+ return 0;
+
+ if (!scrn->last_ust) {
+ xcb_present_notify_msc(scrn->conn,
+ scrn->drawable,
+ ++scrn->send_msc_serial,
+ 0, 0, 0);
+ xcb_flush(scrn->conn);
+
+ while (scrn->special_event &&
+ scrn->send_msc_serial > scrn->recv_msc_serial) {
+ if (!dri3_wait_present_events(scrn))
+ return 0;
+ }
+ }
+
+ return scrn->last_ust;
+}
+
+static void
+vl_dri3_screen_set_next_timestamp(struct vl_screen *vscreen, uint64_t stamp)
+{
+ struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen;
+
+ assert(scrn);
+
+ if (stamp && scrn->last_ust && scrn->ns_frame && scrn->last_msc)
+ scrn->next_msc = ((int64_t)stamp - scrn->last_ust + scrn->ns_frame/2) /
+ scrn->ns_frame + scrn->last_msc;
+ else
+ scrn->next_msc = 0;
+}
+
+static void *
+vl_dri3_screen_get_private(struct vl_screen *vscreen)
+{
+ return vscreen;
+}
+
+static void
+vl_dri3_screen_destroy(struct vl_screen *vscreen)
+{
+ struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen;
+ int i;
+
+ assert(vscreen);
+
+ dri3_flush_present_events(scrn);
+
+ if (scrn->front_buffer) {
+ dri3_free_front_buffer(scrn, scrn->front_buffer);
+ scrn->front_buffer = NULL;
+ return;
+ }
+
+ for (i = 0; i < BACK_BUFFER_NUM; ++i) {
+ if (scrn->back_buffers[i]) {
+ dri3_free_back_buffer(scrn, scrn->back_buffers[i]);
+ scrn->back_buffers[i] = NULL;
+ }
+ }
+
+ if (scrn->special_event) {
+ xcb_void_cookie_t cookie =
+ xcb_present_select_input_checked(scrn->conn, scrn->eid,
+ scrn->drawable,
+ XCB_PRESENT_EVENT_MASK_NO_EVENT);
+
+ xcb_discard_reply(scrn->conn, cookie.sequence);
+ xcb_unregister_for_special_event(scrn->conn, scrn->special_event);
+ }
+ scrn->pipe->destroy(scrn->pipe);
+ scrn->base.pscreen->destroy(scrn->base.pscreen);
+ pipe_loader_release(&scrn->base.dev, 1);
+ FREE(scrn);
+
+ return;
+}
+
+struct vl_screen *
+vl_dri3_screen_create(Display *display, int screen)
+{
+ struct vl_dri3_screen *scrn;
+ const xcb_query_extension_reply_t *extension;
+ xcb_dri3_open_cookie_t open_cookie;
+ xcb_dri3_open_reply_t *open_reply;
+ xcb_get_geometry_cookie_t geom_cookie;
+ xcb_get_geometry_reply_t *geom_reply;
+ int fd;
+
+ assert(display);
+
+ scrn = CALLOC_STRUCT(vl_dri3_screen);
+ if (!scrn)
+ return NULL;
+
+ scrn->conn = XGetXCBConnection(display);
+ if (!scrn->conn)
+ goto free_screen;
+
+ xcb_prefetch_extension_data(scrn->conn , &xcb_dri3_id);
+ xcb_prefetch_extension_data(scrn->conn, &xcb_present_id);
+ extension = xcb_get_extension_data(scrn->conn, &xcb_dri3_id);
+ if (!(extension && extension->present))
+ goto free_screen;
+ extension = xcb_get_extension_data(scrn->conn, &xcb_present_id);
+ if (!(extension && extension->present))
+ goto free_screen;
+
+ open_cookie = xcb_dri3_open(scrn->conn, RootWindow(display, screen), None);
+ open_reply = xcb_dri3_open_reply(scrn->conn, open_cookie, NULL);
+ if (!open_reply)
+ goto free_screen;
+ if (open_reply->nfd != 1) {
+ free(open_reply);
+ goto free_screen;
+ }
+
+ fd = xcb_dri3_open_reply_fds(scrn->conn, open_reply)[0];
+ if (fd < 0) {
+ free(open_reply);
+ goto free_screen;
+ }
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+ free(open_reply);
+
+ fd = loader_get_user_preferred_fd(fd, &scrn->is_different_gpu);
+
+ geom_cookie = xcb_get_geometry(scrn->conn, RootWindow(display, screen));
+ geom_reply = xcb_get_geometry_reply(scrn->conn, geom_cookie, NULL);
+ if (!geom_reply)
+ goto close_fd;
+ /* TODO support depth other than 24 */
+ if (geom_reply->depth != 24) {
+ free(geom_reply);
+ goto close_fd;
+ }
+ free(geom_reply);
+
+ if (pipe_loader_drm_probe_fd(&scrn->base.dev, fd))
+ scrn->base.pscreen = pipe_loader_create_screen(scrn->base.dev);
+
+ if (!scrn->base.pscreen)
+ goto release_pipe;
+
+ scrn->pipe = scrn->base.pscreen->context_create(scrn->base.pscreen,
+ &scrn->base, 0);
+ if (!scrn->pipe)
+ goto no_context;
+
+ scrn->base.destroy = vl_dri3_screen_destroy;
+ scrn->base.texture_from_drawable = vl_dri3_screen_texture_from_drawable;
+ scrn->base.get_dirty_area = vl_dri3_screen_get_dirty_area;
+ scrn->base.get_timestamp = vl_dri3_screen_get_timestamp;
+ scrn->base.set_next_timestamp = vl_dri3_screen_set_next_timestamp;
+ scrn->base.get_private = vl_dri3_screen_get_private;
+ scrn->base.pscreen->flush_frontbuffer = vl_dri3_flush_frontbuffer;
+
+ return &scrn->base;
+
+no_context:
+ scrn->base.pscreen->destroy(scrn->base.pscreen);
+release_pipe:
+ if (scrn->base.dev) {
+ pipe_loader_release(&scrn->base.dev, 1);
+ fd = -1;
+ }
+close_fd:
+ if (fd != -1)
+ close(fd);
+free_screen:
+ FREE(scrn);
+ return NULL;
+}
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_drm.c b/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_drm.c
index 6d9d94758..df8809c50 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_drm.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_winsys_drm.c
@@ -26,6 +26,7 @@
**************************************************************************/
#include <assert.h>
+#include <fcntl.h>
#include "pipe/p_screen.h"
#include "pipe-loader/pipe_loader.h"
@@ -41,20 +42,20 @@ struct vl_screen *
vl_drm_screen_create(int fd)
{
struct vl_screen *vscreen;
- int new_fd = -1;
+ int new_fd;
vscreen = CALLOC_STRUCT(vl_screen);
if (!vscreen)
return NULL;
- if (fd < 0 || (new_fd = dup(fd)) < 0)
- goto error;
+ if (fd < 0 || (new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3)) < 0)
+ goto free_screen;
if (pipe_loader_drm_probe_fd(&vscreen->dev, new_fd))
vscreen->pscreen = pipe_loader_create_screen(vscreen->dev);
if (!vscreen->pscreen)
- goto error;
+ goto release_pipe;
vscreen->destroy = vl_drm_screen_destroy;
vscreen->texture_from_drawable = NULL;
@@ -64,12 +65,13 @@ vl_drm_screen_create(int fd)
vscreen->get_private = NULL;
return vscreen;
-error:
+release_pipe:
if (vscreen->dev)
pipe_loader_release(&vscreen->dev, 1);
else
close(new_fd);
+free_screen:
FREE(vscreen);
return NULL;
}
diff --git a/lib/mesa/src/gallium/auxiliary/vl/vl_zscan.c b/lib/mesa/src/gallium/auxiliary/vl/vl_zscan.c
index 5241471f5..ef05af463 100644
--- a/lib/mesa/src/gallium/auxiliary/vl/vl_zscan.c
+++ b/lib/mesa/src/gallium/auxiliary/vl/vl_zscan.c
@@ -99,17 +99,14 @@ static void *
create_vert_shader(struct vl_zscan *zscan)
{
struct ureg_program *shader;
-
struct ureg_src scale;
struct ureg_src vrect, vpos, block_num;
-
struct ureg_dst tmp;
struct ureg_dst o_vpos;
struct ureg_dst *o_vtex;
+ unsigned i;
- signed i;
-
- shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ shader = ureg_create(PIPE_SHADER_VERTEX);
if (!shader)
return NULL;
@@ -186,7 +183,7 @@ create_frag_shader(struct vl_zscan *zscan)
unsigned i;
- shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ shader = ureg_create(PIPE_SHADER_FRAGMENT);
if (!shader)
return NULL;