Merge remote branch 'origin/master' into pipe-video
authorChristian König <deathsimple@vodafone.de>
Sat, 11 Dec 2010 12:43:44 +0000 (13:43 +0100)
committerChristian König <deathsimple@vodafone.de>
Sat, 11 Dec 2010 12:43:44 +0000 (13:43 +0100)
Conflicts:
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_texture.c

20 files changed:
1  2 
configure.ac
src/gallium/auxiliary/Makefile
src/gallium/auxiliary/SConscript
src/gallium/auxiliary/vl/vl_idct.c
src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/r600/Makefile
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_inlines.h
src/gallium/drivers/r600/r600_texture.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_texture.h
src/gallium/drivers/softpipe/sp_video_context.c
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_screen.h
src/gallium/include/pipe/p_video_context.h
src/gallium/state_trackers/xorg/xvmc/subpicture.c
src/gallium/state_trackers/xorg/xvmc/surface.c
src/gallium/winsys/g3dvl/dri/dri_winsys.c
src/gallium/winsys/g3dvl/vl_winsys.h

diff --cc configure.ac
Simple merge
Simple merge
Simple merge
index f0063a453d09a535984861d72046a433b0c035c5,0000000000000000000000000000000000000000..ae80dc0a2748585a0030d9e73f7893f2969b6a5f
mode 100644,000000..100644
--- /dev/null
@@@ -1,744 -1,0 +1,752 @@@
-       u_subresource(0, 0),
-       PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
 +/**************************************************************************
 + *
 + * Copyright 2010 Christian König
 + * 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 TUNGSTEN GRAPHICS 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 "vl_idct.h"
 +#include "vl_vertex_buffers.h"
 +#include "util/u_draw.h"
 +#include <assert.h>
 +#include <pipe/p_context.h>
 +#include <pipe/p_screen.h>
 +#include <util/u_inlines.h>
 +#include <util/u_sampler.h>
 +#include <util/u_format.h>
 +#include <tgsi/tgsi_ureg.h>
 +#include "vl_types.h"
 +
 +#define BLOCK_WIDTH 8
 +#define BLOCK_HEIGHT 8
 +
 +#define SCALE_FACTOR_16_TO_9 (32768.0f / 256.0f)
 +
 +#define STAGE1_SCALE 4.0f
 +#define STAGE2_SCALE (SCALE_FACTOR_16_TO_9 / STAGE1_SCALE / STAGE1_SCALE)
 +
 +#define NR_RENDER_TARGETS 4
 +
 +enum VS_INPUT
 +{
 +   VS_I_RECT,
 +   VS_I_VPOS,
 +
 +   NUM_VS_INPUTS
 +};
 +
 +enum VS_OUTPUT
 +{
 +   VS_O_VPOS,
 +   VS_O_BLOCK,
 +   VS_O_TEX,
 +   VS_O_START
 +};
 +
 +static const float const_matrix[8][8] = {
 +   {  0.3535530f,  0.3535530f,  0.3535530f,  0.3535530f,  0.3535530f,  0.3535530f,  0.353553f,  0.3535530f },
 +   {  0.4903930f,  0.4157350f,  0.2777850f,  0.0975451f, -0.0975452f, -0.2777850f, -0.415735f, -0.4903930f },
 +   {  0.4619400f,  0.1913420f, -0.1913420f, -0.4619400f, -0.4619400f, -0.1913420f,  0.191342f,  0.4619400f },
 +   {  0.4157350f, -0.0975452f, -0.4903930f, -0.2777850f,  0.2777850f,  0.4903930f,  0.097545f, -0.4157350f },
 +   {  0.3535530f, -0.3535530f, -0.3535530f,  0.3535540f,  0.3535530f, -0.3535540f, -0.353553f,  0.3535530f },
 +   {  0.2777850f, -0.4903930f,  0.0975452f,  0.4157350f, -0.4157350f, -0.0975451f,  0.490393f, -0.2777850f },
 +   {  0.1913420f, -0.4619400f,  0.4619400f, -0.1913420f, -0.1913410f,  0.4619400f, -0.461940f,  0.1913420f },
 +   {  0.0975451f, -0.2777850f,  0.4157350f, -0.4903930f,  0.4903930f, -0.4157350f,  0.277786f, -0.0975458f }
 +};
 +
 +static void *
 +create_vert_shader(struct vl_idct *idct)
 +{
 +   struct ureg_program *shader;
 +   struct ureg_src scale;
 +   struct ureg_src vrect, vpos;
 +   struct ureg_dst t_vpos;
 +   struct ureg_dst o_vpos, o_block, o_tex, o_start;
 +
 +   shader = ureg_create(TGSI_PROCESSOR_VERTEX);
 +   if (!shader)
 +      return NULL;
 +
 +   t_vpos = ureg_DECL_temporary(shader);
 +
 +   vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
 +   vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);
 +
 +   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
 +   o_block = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_BLOCK);
 +   o_tex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX);
 +   o_start = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_START);
 +
 +   /*
 +    * scale = (BLOCK_WIDTH, BLOCK_HEIGHT) / (dst.width, dst.height)
 +    *
 +    * t_vpos = vpos + vrect
 +    * o_vpos.xy = t_vpos * scale
 +    * o_vpos.zw = vpos
 +    *
 +    * o_block = vrect
 +    * o_tex = t_pos
 +    * o_start = vpos * scale
 +    *
 +    */
 +   scale = ureg_imm2f(shader,
 +      (float)BLOCK_WIDTH / idct->buffer_width,
 +      (float)BLOCK_HEIGHT / idct->buffer_height);
 +
 +   ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect);
 +   ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), scale);
 +   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos));
 +   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), vpos);
 +
 +   ureg_MOV(shader, ureg_writemask(o_block, TGSI_WRITEMASK_XY), vrect);
 +   ureg_MOV(shader, ureg_writemask(o_block, TGSI_WRITEMASK_Z), ureg_imm1f(shader, 0.0f));
 +
 +   ureg_MOV(shader, ureg_writemask(o_tex, TGSI_WRITEMASK_XY), ureg_src(t_vpos));
 +#if NR_RENDER_TARGETS == 1
 +   ureg_MOV(shader, ureg_writemask(o_tex, TGSI_WRITEMASK_Z), ureg_imm1f(shader, 0.0f));
 +#else
 +   ureg_MUL(shader, ureg_writemask(o_tex, TGSI_WRITEMASK_Z), 
 +      ureg_scalar(vrect, TGSI_SWIZZLE_X),
 +      ureg_imm1f(shader, BLOCK_WIDTH / NR_RENDER_TARGETS));
 +#endif
 +
 +   ureg_MUL(shader, ureg_writemask(o_start, TGSI_WRITEMASK_XY), vpos, scale);
 +
 +   ureg_release_temporary(shader, t_vpos);
 +
 +   ureg_END(shader);
 +
 +   return ureg_create_shader_and_destroy(shader, idct->pipe);
 +}
 +
 +static void
 +fetch_four(struct ureg_program *shader, struct ureg_dst m[2],
 +           struct ureg_src tc, struct ureg_src sampler,
 +           struct ureg_src start, bool right_side,
 +           bool transposed, float size)
 +{
 +   struct ureg_dst t_tc;
 +   unsigned wm_start = (right_side == transposed) ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_Y;
 +   unsigned wm_tc = (right_side == transposed) ? TGSI_WRITEMASK_Y : TGSI_WRITEMASK_X;
 +
 +   t_tc = ureg_DECL_temporary(shader);
 +   m[0] = ureg_DECL_temporary(shader);
 +   m[1] = ureg_DECL_temporary(shader);
 +
 +   /*
 +    * t_tc.x = right_side ? start.x : tc.x
 +    * t_tc.y = right_side ? tc.y : start.y
 +    * m[0..1] = tex(t_tc++, sampler)
 +    */
 +   if(!right_side) {
 +      ureg_MOV(shader, ureg_writemask(t_tc, wm_start), ureg_scalar(start, TGSI_SWIZZLE_X));
 +      ureg_MOV(shader, ureg_writemask(t_tc, wm_tc), ureg_scalar(tc, TGSI_SWIZZLE_Y));
 +   } else {
 +      ureg_MOV(shader, ureg_writemask(t_tc, wm_start), ureg_scalar(start, TGSI_SWIZZLE_Y));
 +      ureg_MOV(shader, ureg_writemask(t_tc, wm_tc), ureg_scalar(tc, TGSI_SWIZZLE_X));
 +   }
 +   ureg_FRC(shader, ureg_writemask(t_tc, TGSI_WRITEMASK_Z), tc);
 +
 +   ureg_TEX(shader, m[0], TGSI_TEXTURE_3D, ureg_src(t_tc), sampler);
 +   ureg_ADD(shader, ureg_writemask(t_tc, wm_start), ureg_src(t_tc), ureg_imm1f(shader, 1.0f / size));
 +   ureg_TEX(shader, m[1], TGSI_TEXTURE_3D, ureg_src(t_tc), sampler);
 +
 +   ureg_release_temporary(shader, t_tc);
 +}
 +
 +static void
 +matrix_mul(struct ureg_program *shader, struct ureg_dst dst, struct ureg_dst l[2], struct ureg_dst r[2])
 +{
 +   struct ureg_dst tmp[2];
 +   unsigned i;
 +
 +   for(i = 0; i < 2; ++i) {
 +      tmp[i] = ureg_DECL_temporary(shader);
 +   }
 +
 +   /*
 +    * tmp[0..1] = dot4(m[0][0..1], m[1][0..1])
 +    * dst = tmp[0] + tmp[1]
 +    */
 +   ureg_DP4(shader, ureg_writemask(tmp[0], TGSI_WRITEMASK_X), ureg_src(l[0]), ureg_src(r[0]));
 +   ureg_DP4(shader, ureg_writemask(tmp[1], TGSI_WRITEMASK_X), ureg_src(l[1]), ureg_src(r[1]));
 +   ureg_ADD(shader, dst,
 +      ureg_scalar(ureg_src(tmp[0]), TGSI_SWIZZLE_X),
 +      ureg_scalar(ureg_src(tmp[1]), TGSI_SWIZZLE_X));
 +
 +   for(i = 0; i < 2; ++i) {
 +      ureg_release_temporary(shader, tmp[i]);
 +   }
 +}
 +
 +static void *
 +create_transpose_frag_shader(struct vl_idct *idct)
 +{
 +   struct ureg_program *shader;
 +
 +   struct ureg_src block, tex, sampler[2];
 +   struct ureg_src start[2];
 +
 +   struct ureg_dst l[2], r[2];
 +   struct ureg_dst tmp, fragment;
 +
 +   shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
 +   if (!shader)
 +      return NULL;
 +
 +   block = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_BLOCK, TGSI_INTERPOLATE_LINEAR);
 +   tex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX, TGSI_INTERPOLATE_CONSTANT);
 +
 +   sampler[0] = ureg_DECL_sampler(shader, 0);
 +   sampler[1] = ureg_DECL_sampler(shader, 1);
 +
 +   start[0] = ureg_imm1f(shader, 0.0f);
 +   start[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_START, TGSI_INTERPOLATE_CONSTANT);
 +
 +   fetch_four(shader, l, block, sampler[0], start[0], false, false, BLOCK_WIDTH / 4);
 +   fetch_four(shader, r, tex, sampler[1], start[1], true, false, idct->buffer_height / 4);
 +
 +   fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
 +
 +   tmp = ureg_DECL_temporary(shader);
 +   matrix_mul(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), l, r);
 +   ureg_MUL(shader, fragment, ureg_src(tmp), ureg_imm1f(shader, STAGE2_SCALE));
 +
 +   ureg_release_temporary(shader, tmp);
 +   ureg_release_temporary(shader, l[0]);
 +   ureg_release_temporary(shader, l[1]);
 +   ureg_release_temporary(shader, r[0]);
 +   ureg_release_temporary(shader, r[1]);
 +
 +   ureg_END(shader);
 +
 +   return ureg_create_shader_and_destroy(shader, idct->pipe);
 +}
 +
 +static void *
 +create_matrix_frag_shader(struct vl_idct *idct)
 +{
 +   struct ureg_program *shader;
 +
 +   struct ureg_src tex, block, sampler[2];
 +   struct ureg_src start[2];
 +
 +   struct ureg_dst l[4][2], r[2];
 +   struct ureg_dst t_tc, tmp, fragment[NR_RENDER_TARGETS];
 +
 +   unsigned i, j;
 +
 +   shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
 +   if (!shader)
 +      return NULL;
 +
 +   t_tc = ureg_DECL_temporary(shader);
 +   tmp = ureg_DECL_temporary(shader);
 +
 +   tex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX, TGSI_INTERPOLATE_LINEAR);
 +   block = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_BLOCK, TGSI_INTERPOLATE_LINEAR);
 +
 +   sampler[0] = ureg_DECL_sampler(shader, 1);
 +   sampler[1] = ureg_DECL_sampler(shader, 0);
 +
 +   start[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_START, TGSI_INTERPOLATE_CONSTANT);
 +   start[1] = ureg_imm1f(shader, 0.0f);
 +
 +   for (i = 0; i < NR_RENDER_TARGETS; ++i)
 +       fragment[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, i);
 +
 +   for (i = 0; i < 4; ++i) {
 +      if(i == 0)
 +         ureg_MOV(shader, ureg_writemask(t_tc, TGSI_WRITEMASK_Y), tex);
 +      else
 +         ureg_ADD(shader, ureg_writemask(t_tc, TGSI_WRITEMASK_Y), 
 +            ureg_src(t_tc), ureg_imm1f(shader, 1.0f / idct->buffer_height));
 +
 +      fetch_four(shader, l[i], ureg_src(t_tc), sampler[0], start[0], false, false, idct->buffer_width / 4);
 +   }
 +   
 +   for (i = 0; i < NR_RENDER_TARGETS; ++i) {
 +
 +#if NR_RENDER_TARGETS == 1
 +      fetch_four(shader, r, block, sampler[1], start[1], true, true, BLOCK_WIDTH / 4);
 +#else
 +      ureg_ADD(shader, ureg_writemask(t_tc, TGSI_WRITEMASK_X), 
 +         ureg_imm1f(shader, 1.0f / BLOCK_WIDTH * i),
 +         block);
 +      fetch_four(shader, r, ureg_src(t_tc), sampler[1], start[1], true, true, BLOCK_WIDTH / 4);
 +#endif
 +
 +      for (j = 0; j < 4; ++j) {
 +         matrix_mul(shader, ureg_writemask(fragment[i], TGSI_WRITEMASK_X << j), l[j], r);
 +      }
 +      ureg_release_temporary(shader, r[0]);
 +      ureg_release_temporary(shader, r[1]);
 +   }
 +
 +   ureg_release_temporary(shader, t_tc);
 +   ureg_release_temporary(shader, tmp);
 +
 +   for (i = 0; i < 4; ++i) {
 +      ureg_release_temporary(shader, l[i][0]);
 +      ureg_release_temporary(shader, l[i][1]);
 +   }
 +
 +   ureg_END(shader);
 +
 +   return ureg_create_shader_and_destroy(shader, idct->pipe);
 +}
 +
 +static bool
 +init_shaders(struct vl_idct *idct)
 +{
 +   idct->vs = create_vert_shader(idct);
 +   idct->matrix_fs = create_matrix_frag_shader(idct);
 +   idct->transpose_fs = create_transpose_frag_shader(idct);
 +
 +   return 
 +      idct->vs != NULL &&
 +      idct->transpose_fs != NULL &&
 +      idct->matrix_fs != NULL;
 +}
 +
 +static void
 +cleanup_shaders(struct vl_idct *idct)
 +{
 +   idct->pipe->delete_vs_state(idct->pipe, idct->vs);
 +   idct->pipe->delete_fs_state(idct->pipe, idct->matrix_fs);
 +   idct->pipe->delete_fs_state(idct->pipe, idct->transpose_fs);
 +}
 +
 +static bool
 +init_state(struct vl_idct *idct)
 +{
 +   struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS];
 +   struct pipe_sampler_state sampler;
 +   struct pipe_rasterizer_state rs_state;
 +   unsigned i;
 +
 +   assert(idct);
 +
 +   idct->quad = vl_vb_upload_quads(idct->pipe, idct->max_blocks);
 +
 +   if(idct->quad.buffer == NULL)
 +      return false;
 +
 +   for (i = 0; i < 4; ++i) {
 +      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;
 +      /*sampler.shadow_ambient = ; */
 +      /*sampler.lod_bias = ; */
 +      sampler.min_lod = 0;
 +      /*sampler.max_lod = ; */
 +      /*sampler.border_color[0] = ; */
 +      /*sampler.max_anisotropy = ; */
 +      idct->samplers.all[i] = idct->pipe->create_sampler_state(idct->pipe, &sampler);
 +   }
 +
 +   memset(&rs_state, 0, sizeof(rs_state));
 +   /*rs_state.sprite_coord_enable */
 +   rs_state.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
 +   rs_state.point_quad_rasterization = true;
 +   rs_state.point_size = BLOCK_WIDTH;
 +   rs_state.gl_rasterization_rules = false;
 +   idct->rs_state = idct->pipe->create_rasterizer_state(idct->pipe, &rs_state);
 +
 +   vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element();
 +
 +   /* Pos element */
 +   vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R32G32_FLOAT;
 +
 +   idct->vertex_buffer_stride = vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 1, 1);
 +   idct->vertex_elems_state = idct->pipe->create_vertex_elements_state(idct->pipe, 2, vertex_elems);
 +
 +   return true;
 +}
 +
 +static void
 +cleanup_state(struct vl_idct *idct)
 +{
 +   unsigned i;
 +
 +   for (i = 0; i < 4; ++i)
 +      idct->pipe->delete_sampler_state(idct->pipe, idct->samplers.all[i]);
 +
 +   idct->pipe->delete_rasterizer_state(idct->pipe, idct->rs_state);
 +   idct->pipe->delete_vertex_elements_state(idct->pipe, idct->vertex_elems_state);
 +}
 +
 +static bool
 +init_textures(struct vl_idct *idct, struct vl_idct_buffer *buffer)
 +{
 +   struct pipe_resource template;
 +   struct pipe_sampler_view sampler_view;
 +   unsigned i;
 +
 +   assert(idct && buffer);
 +
 +   /* create textures */
 +   memset(&template, 0, sizeof(struct pipe_resource));
 +   template.last_level = 0;
 +   template.depth0 = 1;
 +   template.bind = PIPE_BIND_SAMPLER_VIEW;
 +   template.flags = 0;
 +
 +   template.target = PIPE_TEXTURE_2D;
 +   template.format = PIPE_FORMAT_R16G16B16A16_SNORM;
 +   template.width0 = idct->buffer_width / 4;
 +   template.height0 = idct->buffer_height;
 +   template.depth0 = 1;
 +   template.usage = PIPE_USAGE_STREAM;
 +   buffer->textures.individual.source = idct->pipe->screen->resource_create(idct->pipe->screen, &template);
 +
 +   template.target = PIPE_TEXTURE_3D;
 +   template.format = PIPE_FORMAT_R16G16B16A16_SNORM;
 +   template.width0 = idct->buffer_width / NR_RENDER_TARGETS;
 +   template.height0 = idct->buffer_height / 4;
 +   template.depth0 = NR_RENDER_TARGETS;
 +   template.usage = PIPE_USAGE_STATIC;
 +   buffer->textures.individual.intermediate = idct->pipe->screen->resource_create(idct->pipe->screen, &template);
 +
 +   for (i = 0; i < 4; ++i) {
 +      if(buffer->textures.all[i] == NULL)
 +         return false; /* a texture failed to allocate */
 +
 +      u_sampler_view_default_template(&sampler_view, buffer->textures.all[i], buffer->textures.all[i]->format);
 +      buffer->sampler_views.all[i] = idct->pipe->create_sampler_view(idct->pipe, buffer->textures.all[i], &sampler_view);
 +   }
 +
 +   return true;
 +}
 +
 +static void
 +cleanup_textures(struct vl_idct *idct, struct vl_idct_buffer *buffer)
 +{
 +   unsigned i;
 +
 +   assert(idct && buffer);
 +
 +   for (i = 0; i < 4; ++i) {
 +      pipe_sampler_view_reference(&buffer->sampler_views.all[i], NULL);
 +      pipe_resource_reference(&buffer->textures.all[i], NULL);
 +   }
 +}
 +
 +static bool
 +init_vertex_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
 +{
 +   assert(idct && buffer);
 +
 +   buffer->vertex_bufs.individual.quad.stride = idct->quad.stride;
 +   buffer->vertex_bufs.individual.quad.max_index = idct->quad.max_index;
 +   buffer->vertex_bufs.individual.quad.buffer_offset = idct->quad.buffer_offset;
 +   pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, idct->quad.buffer);
 +
 +   buffer->vertex_bufs.individual.pos = vl_vb_init(
 +      &buffer->blocks, idct->pipe, idct->max_blocks, 2,
 +      idct->vertex_buffer_stride);
 +
 +   if(buffer->vertex_bufs.individual.pos.buffer == NULL)
 +      return false;
 +
 +   return true;
 +}
 +
 +static void
 +cleanup_vertex_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
 +{
 +   assert(idct && buffer);
 +
 +   pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, NULL);
 +   pipe_resource_reference(&buffer->vertex_bufs.individual.pos.buffer, NULL);
 +
 +   vl_vb_cleanup(&buffer->blocks);
 +}
 +
 +struct pipe_resource *
 +vl_idct_upload_matrix(struct pipe_context *pipe)
 +{
 +   struct pipe_resource template, *matrix;
 +   struct pipe_transfer *buf_transfer;
 +   unsigned i, j, pitch;
 +   float *f;
 +
 +   struct pipe_box rect =
 +   {
 +      0, 0, 0,
 +      BLOCK_WIDTH / 4,
 +      BLOCK_HEIGHT,
 +      1
 +   };
 +
 +   memset(&template, 0, sizeof(struct pipe_resource));
 +   template.target = PIPE_TEXTURE_2D;
 +   template.format = PIPE_FORMAT_R32G32B32A32_FLOAT;
 +   template.last_level = 0;
 +   template.width0 = 2;
 +   template.height0 = 8;
 +   template.depth0 = 1;
 +   template.usage = PIPE_USAGE_IMMUTABLE;
 +   template.bind = PIPE_BIND_SAMPLER_VIEW;
 +   template.flags = 0;
 +
 +   matrix = pipe->screen->resource_create(pipe->screen, &template);
 +
 +   /* matrix */
 +   buf_transfer = pipe->get_transfer
 +   (
 +      pipe, matrix,
-       buffer->fb_state[0].cbufs[i] = idct->pipe->screen->get_tex_surface(
-          idct->pipe->screen, buffer->textures.individual.intermediate, 0, 0, i,
-          PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET);
++      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
 +      &rect
 +   );
 +   pitch = buf_transfer->stride / sizeof(float);
 +
 +   f = pipe->transfer_map(pipe, buf_transfer);
 +   for(i = 0; i < BLOCK_HEIGHT; ++i)
 +      for(j = 0; j < BLOCK_WIDTH; ++j)
 +         // transpose and scale
 +         f[i * pitch + j] = const_matrix[j][i] * STAGE1_SCALE;
 +
 +   pipe->transfer_unmap(pipe, buf_transfer);
 +   pipe->transfer_destroy(pipe, buf_transfer);
 +
 +   return matrix;
 +}
 +
 +bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe, 
 +                  unsigned buffer_width, unsigned buffer_height,
 +                  struct pipe_resource *matrix)
 +{
 +   assert(idct && pipe && matrix);
 +
 +   idct->pipe = pipe;
 +   idct->buffer_width = buffer_width;
 +   idct->buffer_height = buffer_height;
 +   pipe_resource_reference(&idct->matrix, matrix);
 +
 +   idct->max_blocks =
 +      align(buffer_width, BLOCK_WIDTH) / BLOCK_WIDTH *
 +      align(buffer_height, BLOCK_HEIGHT) / BLOCK_HEIGHT;
 +
 +   if(!init_shaders(idct))
 +      return false;
 +
 +   if(!init_state(idct)) {
 +      cleanup_shaders(idct);
 +      return false;
 +   }
 +
 +   return true;
 +}
 +
 +void
 +vl_idct_cleanup(struct vl_idct *idct)
 +{
 +   cleanup_shaders(idct);
 +   cleanup_state(idct);
 +
 +   pipe_resource_reference(&idct->matrix, NULL);
 +}
 +
 +bool
 +vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer, struct pipe_resource *dst)
 +{
++   struct pipe_surface template;
++
 +   unsigned i;
 +
 +   assert(buffer);
 +   assert(idct);
 +   assert(dst);
 +
 +   pipe_resource_reference(&buffer->textures.individual.matrix, idct->matrix);
 +   pipe_resource_reference(&buffer->textures.individual.transpose, idct->matrix);
 +   pipe_resource_reference(&buffer->destination, dst);
 +
 +   if (!init_textures(idct, buffer))
 +      return false;
 +
 +   if (!init_vertex_buffers(idct, buffer))
 +      return false;
 +
 +   /* init state */
 +   buffer->viewport[0].scale[0] = buffer->textures.individual.intermediate->width0;
 +   buffer->viewport[0].scale[1] = buffer->textures.individual.intermediate->height0;
 +
 +   buffer->viewport[1].scale[0] = buffer->destination->width0;
 +   buffer->viewport[1].scale[1] = buffer->destination->height0;
 +
 +   buffer->fb_state[0].width = buffer->textures.individual.intermediate->width0;
 +   buffer->fb_state[0].height = buffer->textures.individual.intermediate->height0;
 +
 +   buffer->fb_state[0].nr_cbufs = NR_RENDER_TARGETS;
 +   for(i = 0; i < NR_RENDER_TARGETS; ++i) {
-    buffer->fb_state[1].cbufs[0] = idct->pipe->screen->get_tex_surface(
-       idct->pipe->screen, buffer->destination, 0, 0, 0,
-       PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET);
++      memset(&template, 0, sizeof(template));
++      template.format = buffer->textures.individual.intermediate->format;
++      template.u.tex.first_layer = i;
++      template.u.tex.last_layer = i;
++      template.usage = PIPE_BIND_RENDER_TARGET;
++      buffer->fb_state[0].cbufs[i] = idct->pipe->create_surface(
++         idct->pipe, buffer->textures.individual.intermediate,
++         &template);
 +   }
 +
 +   buffer->fb_state[1].width = buffer->destination->width0;
 +   buffer->fb_state[1].height = buffer->destination->height0;
 +
 +   buffer->fb_state[1].nr_cbufs = 1;
-       idct->pipe->screen->tex_surface_destroy(buffer->fb_state[0].cbufs[i]);
++
++   memset(&template, 0, sizeof(template));
++   template.format = buffer->destination->format;
++   template.usage = PIPE_BIND_RENDER_TARGET;
++   buffer->fb_state[1].cbufs[0] = idct->pipe->create_surface(
++      idct->pipe, buffer->destination, &template);
 +
 +   for(i = 0; i < 2; ++i) {
 +      buffer->viewport[i].scale[2] = 1;
 +      buffer->viewport[i].scale[3] = 1;
 +      buffer->viewport[i].translate[0] = 0;
 +      buffer->viewport[i].translate[1] = 0;
 +      buffer->viewport[i].translate[2] = 0;
 +      buffer->viewport[i].translate[3] = 0;
 +
 +      buffer->fb_state[i].zsbuf = NULL;
 +   }
 +
 +   return true;
 +}
 +
 +void
 +vl_idct_cleanup_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer)
 +{
 +   unsigned i;
 +
 +   assert(buffer);
 +
 +   for(i = 0; i < NR_RENDER_TARGETS; ++i) {
-    idct->pipe->screen->tex_surface_destroy(buffer->fb_state[1].cbufs[0]);
++      idct->pipe->surface_destroy(idct->pipe, buffer->fb_state[0].cbufs[i]);
 +   }
 +
-       u_subresource(0, 0),
-       PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
++   idct->pipe->surface_destroy(idct->pipe, buffer->fb_state[1].cbufs[0]);
 +
 +   cleanup_textures(idct, buffer);
 +   cleanup_vertex_buffers(idct, buffer);
 +}
 +
 +void
 +vl_idct_map_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
 +{
 +   assert(idct);
 +
 +   struct pipe_box rect =
 +   {
 +      0, 0, 0,
 +      buffer->textures.individual.source->width0,
 +      buffer->textures.individual.source->height0,
 +      1
 +   };
 +
 +   buffer->tex_transfer = idct->pipe->get_transfer
 +   (
 +      idct->pipe, buffer->textures.individual.source,
++      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
 +      &rect
 +   );
 +
 +   buffer->texels = idct->pipe->transfer_map(idct->pipe, buffer->tex_transfer);
 +
 +   vl_vb_map(&buffer->blocks, idct->pipe);
 +}
 +
 +void
 +vl_idct_add_block(struct vl_idct_buffer *buffer, unsigned x, unsigned y, short *block)
 +{
 +   struct vertex2f v;
 +   unsigned tex_pitch;
 +   short *texels;
 +
 +   unsigned i;
 +
 +   assert(buffer);
 +
 +   tex_pitch = buffer->tex_transfer->stride / sizeof(short);
 +   texels = buffer->texels + y * tex_pitch * BLOCK_HEIGHT + x * BLOCK_WIDTH;
 +
 +   for (i = 0; i < BLOCK_HEIGHT; ++i)
 +      memcpy(texels + i * tex_pitch, block + i * BLOCK_WIDTH, BLOCK_WIDTH * sizeof(short));
 +
 +   v.x = x;
 +   v.y = y;
 +   vl_vb_add_block(&buffer->blocks, (float*)&v);
 +}
 +
 +void
 +vl_idct_unmap_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
 +{
 +   assert(idct && buffer);
 +
 +   idct->pipe->transfer_unmap(idct->pipe, buffer->tex_transfer);
 +   idct->pipe->transfer_destroy(idct->pipe, buffer->tex_transfer);
 +   vl_vb_unmap(&buffer->blocks, idct->pipe);
 +}
 +
 +void
 +vl_idct_flush(struct vl_idct *idct, struct vl_idct_buffer *buffer)
 +{
 +   unsigned num_verts;
 +
 +   assert(idct);
 +
 +   num_verts = vl_vb_restart(&buffer->blocks);
 +
 +   if(num_verts > 0) {
 +
 +      idct->pipe->bind_rasterizer_state(idct->pipe, idct->rs_state);
 +      idct->pipe->set_vertex_buffers(idct->pipe, 2, buffer->vertex_bufs.all);
 +      idct->pipe->bind_vertex_elements_state(idct->pipe, idct->vertex_elems_state);
 +      idct->pipe->bind_vs_state(idct->pipe, idct->vs);
 +
 +      /* first stage */
 +      idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state[0]);
 +      idct->pipe->set_viewport_state(idct->pipe, &buffer->viewport[0]);
 +      idct->pipe->set_fragment_sampler_views(idct->pipe, 2, buffer->sampler_views.stage[0]);
 +      idct->pipe->bind_fragment_sampler_states(idct->pipe, 2, idct->samplers.stage[0]);
 +      idct->pipe->bind_fs_state(idct->pipe, idct->matrix_fs);
 +      util_draw_arrays(idct->pipe, PIPE_PRIM_QUADS, 0, num_verts);
 +
 +      /* second stage */
 +      idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state[1]);
 +      idct->pipe->set_viewport_state(idct->pipe, &buffer->viewport[1]);
 +      idct->pipe->set_fragment_sampler_views(idct->pipe, 2, buffer->sampler_views.stage[1]);
 +      idct->pipe->bind_fragment_sampler_states(idct->pipe, 2, idct->samplers.stage[1]);
 +      idct->pipe->bind_fs_state(idct->pipe, idct->transpose_fs);
 +      util_draw_arrays(idct->pipe, PIPE_PRIM_QUADS, 0, num_verts);
 +   }
 +}
Simple merge
index 3bfba99dcaf073dbd9da7986c01ea477232c4d38,72988b946e50d5b26578503d4980d811cec23bf0..69cb5f7751fedfb5a09c4ca8d437233b207fca1d
@@@ -464,8 -471,6 +472,7 @@@ struct pipe_screen *r600_screen_create(
        rscreen->screen.get_paramf = r600_get_paramf;
        rscreen->screen.is_format_supported = r600_is_format_supported;
        rscreen->screen.context_create = r600_create_context;
-       r600_init_screen_texture_functions(&rscreen->screen);
 +      rscreen->screen.video_context_create = r600_video_create;
        r600_init_screen_resource_functions(&rscreen->screen);
  
        rscreen->tiling_info = r600_get_tiling_info(radeon);
Simple merge
index 65d6acb9e4cfa7e265bb9eb5ac7a0479187ad972,d4d9b07c0e8a4aba003416a351aa411550f9dfdd..23e239c006886a6534d64f8126b64edcfe542016
@@@ -559,25 -549,23 +549,24 @@@ struct pipe_transfer* r600_texture_get_
        if (rtex->tiled)
                use_staging_texture = TRUE;
  
-       if ((usage & PIPE_TRANSFER_READ) &&
-             u_box_volume(box) > 1024)
-                 use_staging_texture = TRUE;
-         /* XXX: Use a staging texture for uploads if the underlying BO
-          * is busy.  No interface for checking that currently? so do
-          * it eagerly whenever the transfer doesn't require a readback
-          * and might block.
-          */
-         if ((usage & PIPE_TRANSFER_WRITE) &&
-             !(usage & (PIPE_TRANSFER_READ |
-                        PIPE_TRANSFER_DONTBLOCK |
-                        PIPE_TRANSFER_UNSYNCHRONIZED)))
-                 use_staging_texture = TRUE;
-         if (!permit_hardware_blit(ctx->screen, texture) ||
-             (texture->flags & R600_RESOURCE_FLAG_TRANSFER) ||
-             (texture->usage == PIPE_USAGE_STREAM))
-                 use_staging_texture = FALSE;
+       if ((usage & PIPE_TRANSFER_READ) && u_box_volume(box) > 1024)
+               use_staging_texture = TRUE;
+       /* XXX: Use a staging texture for uploads if the underlying BO
+        * is busy.  No interface for checking that currently? so do
+        * it eagerly whenever the transfer doesn't require a readback
+        * and might block.
+        */
+       if ((usage & PIPE_TRANSFER_WRITE) &&
+                       !(usage & (PIPE_TRANSFER_READ |
+                                       PIPE_TRANSFER_DONTBLOCK |
+                                       PIPE_TRANSFER_UNSYNCHRONIZED)))
+               use_staging_texture = TRUE;
+       if (!permit_hardware_blit(ctx->screen, texture) ||
 -              (texture->flags & R600_RESOURCE_FLAG_TRANSFER))
++              (texture->flags & R600_RESOURCE_FLAG_TRANSFER) ||
++              (texture->usage == PIPE_USAGE_STREAM))
+               use_staging_texture = FALSE;
  
        trans = CALLOC_STRUCT(r600_transfer);
        if (trans == NULL)
index 355ad75064c8d65d6862300de783c847abccf7c5,0000000000000000000000000000000000000000..895aab1b2b1a29ce3f1e9dc075ee90f75bf6be2a
mode 100644,000000..100644
--- /dev/null
@@@ -1,631 -1,0 +1,645 @@@
-    struct pipe_subresource subdst, subsrc;
-    subdst.face = dst->face;
-    subdst.level = dst->level;
-    subsrc.face = src->face;
-    subsrc.level = src->level;
 +/**************************************************************************
 + *
 + * Copyright 2009 Younes Manton.
 + * 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 TUNGSTEN GRAPHICS 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 "util/u_inlines.h"
 +#include "util/u_memory.h"
 +
 +#include "sp_video_context.h"
 +#include <util/u_inlines.h>
 +#include <util/u_memory.h>
 +#include <util/u_keymap.h>
 +#include <util/u_rect.h>
 +#include <util/u_video.h>
 +#include <util/u_surface.h>
 +#include "sp_public.h"
 +#include "sp_texture.h"
 +
 +#define NUM_BUFFERS 2
 +
 +static void
 +flush_buffer(struct sp_mpeg12_context *ctx)
 +{
 +   assert(ctx);
 +
 +   if(ctx->mc_buffer != NULL) {
 +
 +      vl_mpeg12_mc_unmap_buffer(&ctx->mc_renderer, ctx->mc_buffer);
 +      vl_mpeg12_mc_renderer_flush(&ctx->mc_renderer, ctx->mc_buffer);
 +
 +      ctx->mc_buffer = NULL;
 +   }
 +}
 +
 +static void
 +rotate_buffer(struct sp_mpeg12_context *ctx)
 +{
 +   static unsigned key = 0;
 +   struct vl_mpeg12_mc_buffer *buffer;
 +
 +   assert(ctx);
 +
 +   flush_buffer(ctx);
 +
 +   buffer = (struct vl_mpeg12_mc_buffer*)util_keymap_lookup(ctx->buffer_map, &key);
 +   if (!buffer) {
 +      boolean added_to_map;
 +
 +      buffer = CALLOC_STRUCT(vl_mpeg12_mc_buffer);
 +      if (buffer == NULL)
 +         return;
 +
 +      if(!vl_mpeg12_mc_init_buffer(&ctx->mc_renderer, buffer)) {
 +         FREE(buffer);
 +         return;
 +      }
 +
 +      added_to_map = util_keymap_insert(ctx->buffer_map, &key, buffer, ctx);
 +      assert(added_to_map);
 +   }
 +   ++key;
 +   key %= NUM_BUFFERS;
 +   ctx->mc_buffer = buffer;
 +
 +   vl_mpeg12_mc_map_buffer(&ctx->mc_renderer, ctx->mc_buffer);
 +}
 +
 +static void
 +delete_buffer(const struct keymap *map,
 +              const void *key, void *data,
 +              void *user)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)user;
 +   struct vl_mpeg12_mc_buffer *buf = (struct vl_mpeg12_mc_buffer*)data;
 +
 +   assert(map);
 +   assert(key);
 +   assert(data);
 +   assert(user);
 +
 +   vl_mpeg12_mc_cleanup_buffer(&ctx->mc_renderer, buf);
 +}
 +
 +static void
 +sp_mpeg12_destroy(struct pipe_video_context *vpipe)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +
 +   flush_buffer(ctx);
 +
 +   /* Asserted in softpipe_delete_fs_state() for some reason */
 +   ctx->pipe->bind_vs_state(ctx->pipe, NULL);
 +   ctx->pipe->bind_fs_state(ctx->pipe, NULL);
 +
 +   ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend);
 +   ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
 +   ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
 +
 +   pipe_surface_reference(&ctx->decode_target, NULL);
 +   vl_compositor_cleanup(&ctx->compositor);
 +   util_delete_keymap(ctx->buffer_map, ctx);
 +   vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
 +   ctx->pipe->destroy(ctx->pipe);
 +
 +   FREE(ctx);
 +}
 +
 +static int
 +sp_mpeg12_get_param(struct pipe_video_context *vpipe, int param)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +
 +   switch (param) {
 +      case PIPE_CAP_NPOT_TEXTURES:
 +         /* XXX: Temporary; not all paths are NPOT-tested */
 +#if 0
 +         return ctx->pipe->screen->get_param(ctx->pipe->screen, param);
 +#endif
 +         return FALSE;
 +      case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT:
 +         return ctx->decode_format;
 +      default:
 +      {
 +         debug_printf("Softpipe: Unknown PIPE_CAP %d\n", param);
 +         return 0;
 +      }
 +   }
 +}
 +
++static struct pipe_surface *
++sp_mpeg12_create_surface(struct pipe_video_context *vpipe,
++                         struct pipe_resource *resource,
++                         const struct pipe_surface *templat)
++{
++   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
++
++   assert(vpipe);
++
++   return ctx->pipe->create_surface(ctx->pipe, resource, templat);
++}
++
 +static boolean
 +sp_mpeg12_is_format_supported(struct pipe_video_context *vpipe,
 +                              enum pipe_format format,
 +                              unsigned usage,
 +                              unsigned geom)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +
 +   /* XXX: Temporary; not all paths are NPOT-tested */
 +   if (geom & PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)
 +      return FALSE;
 +
 +   return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, format, PIPE_TEXTURE_2D,
 +                                                 0, usage, geom);
 +}
 +
 +static void
 +sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe,
 +                             struct pipe_surface *past,
 +                             struct pipe_surface *future,
 +                             unsigned num_macroblocks,
 +                             struct pipe_macroblock *macroblocks,
 +                             struct pipe_fence_handle **fence)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +   struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks;
 +
 +   assert(vpipe);
 +   assert(num_macroblocks);
 +   assert(macroblocks);
 +   assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
 +   assert(ctx->decode_target);
 +   assert(ctx->mc_buffer);
 +
 +   vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer,
 +                                            ctx->mc_buffer,
 +                                            ctx->decode_target,
 +                                            past, future, num_macroblocks,
 +                                            mpeg12_macroblocks, fence);
 +}
 +
 +static void
 +sp_mpeg12_surface_fill(struct pipe_video_context *vpipe,
 +                       struct pipe_surface *dst,
 +                       unsigned dstx, unsigned dsty,
 +                       unsigned width, unsigned height,
 +                       unsigned value)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +   float rgba[4] = { 0, 0, 0, 0 };
 +
 +   assert(vpipe);
 +   assert(dst);
 +
 +   if (ctx->pipe->clear_render_target)
 +      ctx->pipe->clear_render_target(ctx->pipe, dst, rgba, dstx, dsty, width, height);
 +   else
 +      util_clear_render_target(ctx->pipe, dst, rgba, dstx, dsty, width, height);
 +}
 +
 +static void
 +sp_mpeg12_surface_copy(struct pipe_video_context *vpipe,
 +                       struct pipe_surface *dst,
 +                       unsigned dstx, unsigned dsty,
 +                       struct pipe_surface *src,
 +                       unsigned srcx, unsigned srcy,
 +                       unsigned width, unsigned height)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert(dst);
 +
-       ctx->pipe->resource_copy_region(ctx->pipe, dst->texture, subdst, dstx, dsty, dst->zslice,
-                                       src->texture, subsrc, srcx, srcy, src->zslice,
-                                       width, height);
++   struct pipe_box box;
++   box.x = srcx;
++   box.y = srcy;
++   box.z = 0;
++   box.width = width;
++   box.height = height;
 +
 +   if (ctx->pipe->resource_copy_region)
-       util_resource_copy_region(ctx->pipe, dst->texture, subdst, dstx, dsty, dst->zslice,
-                                 src->texture, subsrc, srcx, srcy, src->zslice,
-                                 width, height);
++      ctx->pipe->resource_copy_region(ctx->pipe, dst->texture, dst->u.tex.level,
++                                      dstx, dsty, dst->u.tex.first_layer,
++                                      src->texture, src->u.tex.level, &box);
 +   else
-                        struct pipe_subresource subresource,
++      util_resource_copy_region(ctx->pipe, dst->texture, dst->u.tex.level,
++                                dstx, dsty, dst->u.tex.first_layer,
++                                src->texture, src->u.tex.level, &box);
 +}
 +
 +static struct pipe_transfer*
 +sp_mpeg12_get_transfer(struct pipe_video_context *vpipe,
 +                       struct pipe_resource *resource,
-    return ctx->pipe->get_transfer(ctx->pipe, resource, subresource, usage, box);
++                       unsigned level,
 +                       unsigned usage,  /* a combination of PIPE_TRANSFER_x */
 +                       const struct pipe_box *box)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert(resource);
 +   assert(box);
 +
-                                 struct pipe_subresource subresource,
++   return ctx->pipe->get_transfer(ctx->pipe, resource, level, usage, box);
 +}
 +
 +static void
 +sp_mpeg12_transfer_destroy(struct pipe_video_context *vpipe,
 +                           struct pipe_transfer *transfer)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert(transfer);
 +
 +   ctx->pipe->transfer_destroy(ctx->pipe, transfer);
 +}
 +
 +static void*
 +sp_mpeg12_transfer_map(struct pipe_video_context *vpipe,
 +                       struct pipe_transfer *transfer)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert(transfer);
 +
 +   return ctx->pipe->transfer_map(ctx->pipe, transfer);
 +}
 +
 +static void
 +sp_mpeg12_transfer_flush_region(struct pipe_video_context *vpipe,
 +                                struct pipe_transfer *transfer,
 +                                const struct pipe_box *box)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert(transfer);
 +   assert(box);
 +
 +   ctx->pipe->transfer_flush_region(ctx->pipe, transfer, box);
 +}
 +
 +static void
 +sp_mpeg12_transfer_unmap(struct pipe_video_context *vpipe,
 +                         struct pipe_transfer *transfer)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert(transfer);
 +
 +   ctx->pipe->transfer_unmap(ctx->pipe, transfer);
 +}
 +
 +static void
 +sp_mpeg12_transfer_inline_write(struct pipe_video_context *vpipe,
 +                                struct pipe_resource *resource,
-    ctx->pipe->transfer_inline_write(ctx->pipe, resource, subresource, usage,
++                                unsigned level,
 +                                unsigned usage, /* a combination of PIPE_TRANSFER_x */
 +                                const struct pipe_box *box,
 +                                const void *data,
 +                                unsigned stride,
 +                                unsigned slice_stride)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert(resource);
 +   assert(box);
 +   assert(data);
 +   assert(ctx->pipe->transfer_inline_write);
 +
++   ctx->pipe->transfer_inline_write(ctx->pipe, resource, level, usage,
 +                                    box, data, stride, slice_stride);
 +}
 +
 +static void
 +sp_mpeg12_render_picture(struct pipe_video_context     *vpipe,
 +                         struct pipe_surface           *src_surface,
 +                         enum pipe_mpeg12_picture_type picture_type,
 +                         /*unsigned                    num_past_surfaces,
 +                         struct pipe_surface           *past_surfaces,
 +                         unsigned                      num_future_surfaces,
 +                         struct pipe_surface           *future_surfaces,*/
 +                         struct pipe_video_rect        *src_area,
 +                         struct pipe_surface           *dst_surface,
 +                         struct pipe_video_rect        *dst_area,
 +                         struct pipe_fence_handle      **fence)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert(src_surface);
 +   assert(src_area);
 +   assert(dst_surface);
 +   assert(dst_area);
 +
 +   flush_buffer(ctx);
 +
 +   vl_compositor_render(&ctx->compositor, src_surface,
 +                        picture_type, src_area, dst_surface, dst_area, fence);
 +}
 +
 +static void
 +sp_mpeg12_set_picture_background(struct pipe_video_context *vpipe,
 +                                  struct pipe_surface *bg,
 +                                  struct pipe_video_rect *bg_src_rect)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert(bg);
 +   assert(bg_src_rect);
 +
 +   vl_compositor_set_background(&ctx->compositor, bg, bg_src_rect);
 +}
 +
 +static void
 +sp_mpeg12_set_picture_layers(struct pipe_video_context *vpipe,
 +                             struct pipe_surface *layers[],
 +                             struct pipe_video_rect *src_rects[],
 +                             struct pipe_video_rect *dst_rects[],
 +                             unsigned num_layers)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert((layers && src_rects && dst_rects) ||
 +          (!layers && !src_rects && !dst_rects));
 +
 +   vl_compositor_set_layers(&ctx->compositor, layers, src_rects, dst_rects, num_layers);
 +}
 +
 +static void
 +sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe,
 +                            struct pipe_surface *dt)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +   assert(dt);
 +
 +   if (ctx->decode_target != dt || ctx->mc_buffer == NULL) {
 +      rotate_buffer(ctx);
 +
 +      pipe_surface_reference(&ctx->decode_target, dt);
 +   }
 +}
 +
 +static void
 +sp_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat)
 +{
 +   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
 +
 +   assert(vpipe);
 +
 +   vl_compositor_set_csc_matrix(&ctx->compositor, mat);
 +}
 +
 +static bool
 +init_pipe_state(struct sp_mpeg12_context *ctx)
 +{
 +   struct pipe_rasterizer_state rast;
 +   struct pipe_blend_state blend;
 +   struct pipe_depth_stencil_alpha_state dsa;
 +   unsigned i;
 +
 +   assert(ctx);
 +
 +   memset(&rast, 0, sizeof rast);
 +   rast.flatshade = 1;
 +   rast.flatshade_first = 0;
 +   rast.light_twoside = 0;
 +   rast.front_ccw = 1;
 +   rast.cull_face = PIPE_FACE_NONE;
 +   rast.fill_back = PIPE_POLYGON_MODE_FILL;
 +   rast.fill_front = PIPE_POLYGON_MODE_FILL;
 +   rast.offset_point = 0;
 +   rast.offset_line = 0;
 +   rast.scissor = 0;
 +   rast.poly_smooth = 0;
 +   rast.poly_stipple_enable = 0;
 +   rast.sprite_coord_enable = 0;
 +   rast.point_size_per_vertex = 0;
 +   rast.multisample = 0;
 +   rast.line_smooth = 0;
 +   rast.line_stipple_enable = 0;
 +   rast.line_stipple_factor = 0;
 +   rast.line_stipple_pattern = 0;
 +   rast.line_last_pixel = 0;
 +   rast.line_width = 1;
 +   rast.point_smooth = 0;
 +   rast.point_quad_rasterization = 0;
 +   rast.point_size = 1;
 +   rast.offset_units = 1;
 +   rast.offset_scale = 1;
 +   rast.gl_rasterization_rules = 1;
 +   ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
 +   ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
 +
 +   memset(&blend, 0, sizeof blend);
 +   blend.independent_blend_enable = 0;
 +   blend.rt[0].blend_enable = 0;
 +   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_enable = 0;
 +   blend.logicop_func = PIPE_LOGICOP_CLEAR;
 +   /* Needed to allow color writes to FB, even if blending disabled */
 +   blend.rt[0].colormask = PIPE_MASK_RGBA;
 +   blend.dither = 0;
 +   ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
 +   ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
 +
 +   memset(&dsa, 0, sizeof dsa);
 +   dsa.depth.enabled = 0;
 +   dsa.depth.writemask = 0;
 +   dsa.depth.func = PIPE_FUNC_ALWAYS;
 +   for (i = 0; i < 2; ++i) {
 +      dsa.stencil[i].enabled = 0;
 +      dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
 +      dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
 +      dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
 +      dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
 +      dsa.stencil[i].valuemask = 0;
 +      dsa.stencil[i].writemask = 0;
 +   }
 +   dsa.alpha.enabled = 0;
 +   dsa.alpha.func = PIPE_FUNC_ALWAYS;
 +   dsa.alpha.ref_value = 0;
 +   ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa);
 +   ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
 +
 +   return true;
 +}
 +
 +static struct pipe_video_context *
 +sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
 +                 enum pipe_video_chroma_format chroma_format,
 +                 unsigned width, unsigned height,
 +                 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
 +                 bool pot_buffers,
 +                 enum pipe_format decode_format)
 +{
 +   unsigned buffer_width, buffer_height;
 +   struct sp_mpeg12_context *ctx;
 +
 +   assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
 +
 +   ctx = CALLOC_STRUCT(sp_mpeg12_context);
 +
 +   if (!ctx)
 +      return NULL;
 +
 +   /* TODO: Non-pot buffers untested, probably doesn't work without changes to texcoord generation, vert shader, etc */
 +   assert(pot_buffers);
 +
 +   buffer_width = pot_buffers ? util_next_power_of_two(width) : width; 
 +   buffer_height = pot_buffers ? util_next_power_of_two(height) : height; 
 +
 +   ctx->base.profile = profile;
 +   ctx->base.chroma_format = chroma_format;
 +   ctx->base.width = width;
 +   ctx->base.height = height;
 +
 +   ctx->base.screen = pipe->screen;
 +   ctx->base.destroy = sp_mpeg12_destroy;
 +   ctx->base.get_param = sp_mpeg12_get_param;
 +   ctx->base.is_format_supported = sp_mpeg12_is_format_supported;
++   ctx->base.create_surface = sp_mpeg12_create_surface;
 +   ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks;
 +   ctx->base.render_picture = sp_mpeg12_render_picture;
 +   ctx->base.surface_fill = sp_mpeg12_surface_fill;
 +   ctx->base.surface_copy = sp_mpeg12_surface_copy;
 +   ctx->base.get_transfer = sp_mpeg12_get_transfer;
 +   ctx->base.transfer_destroy = sp_mpeg12_transfer_destroy;
 +   ctx->base.transfer_map = sp_mpeg12_transfer_map;
 +   ctx->base.transfer_flush_region = sp_mpeg12_transfer_flush_region;
 +   ctx->base.transfer_unmap = sp_mpeg12_transfer_unmap;
 +   if (pipe->transfer_inline_write)
 +      ctx->base.transfer_inline_write = sp_mpeg12_transfer_inline_write;
 +   ctx->base.set_picture_background = sp_mpeg12_set_picture_background;
 +   ctx->base.set_picture_layers = sp_mpeg12_set_picture_layers;
 +   ctx->base.set_decode_target = sp_mpeg12_set_decode_target;
 +   ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix;
 +
 +   ctx->pipe = pipe;
 +   ctx->decode_format = decode_format;
 +
 +   if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
 +                                   buffer_width, buffer_height, chroma_format,
 +                                   bufmode)) {
 +      ctx->pipe->destroy(ctx->pipe);
 +      FREE(ctx);
 +      return NULL;
 +   }
 +
 +   ctx->buffer_map = util_new_keymap(sizeof(unsigned), -1, delete_buffer);
 +   if (!ctx->buffer_map) {
 +      vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
 +      ctx->pipe->destroy(ctx->pipe);
 +      FREE(ctx);
 +      return NULL;
 +   }
 +
 +   if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) {
 +      util_delete_keymap(ctx->buffer_map, ctx);
 +      vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
 +      ctx->pipe->destroy(ctx->pipe);
 +      FREE(ctx);
 +      return NULL;
 +   }
 +
 +   if (!init_pipe_state(ctx)) {
 +      vl_compositor_cleanup(&ctx->compositor);
 +      util_delete_keymap(ctx->buffer_map, ctx);
 +      vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
 +      ctx->pipe->destroy(ctx->pipe);
 +      FREE(ctx);
 +      return NULL;
 +   }
 +
 +   return &ctx->base;
 +}
 +
 +struct pipe_video_context *
 +sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
 +                enum pipe_video_chroma_format chroma_format,
 +                unsigned width, unsigned height, void *priv)
 +{
 +   struct pipe_context *pipe;
 +
 +   assert(screen);
 +   assert(width && height);
 +
 +   pipe = screen->context_create(screen, NULL);
 +   if (!pipe)
 +      return NULL;
 +
 +   /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */
 +   return sp_video_create_ex(pipe, profile,
 +                             chroma_format,
 +                             width, height,
 +                             VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
 +                             true,
 +                             PIPE_FORMAT_XYUV);
 +}
 +
 +struct pipe_video_context *
 +sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile,
 +                   enum pipe_video_chroma_format chroma_format,
 +                   unsigned width, unsigned height,
 +                   enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
 +                   bool pot_buffers,
 +                   enum pipe_format decode_format)
 +{
 +   assert(pipe);
 +   assert(width && height);
 +
 +   switch (u_reduce_video_profile(profile)) {
 +      case PIPE_VIDEO_CODEC_MPEG12:
 +         return sp_mpeg12_create(pipe, profile,
 +                                 chroma_format,
 +                                 width, height,
 +                                 bufmode,
 +                                 pot_buffers,
 +                                 decode_format);
 +      default:
 +         return NULL;
 +   }
 +}
Simple merge
Simple merge
index 294dc464c36a3f8b9c341d3981d8fa3d5641caa0,0000000000000000000000000000000000000000..2dfdba413ac6d52173fd24d7300a854566f9e127
mode 100644,000000..100644
--- /dev/null
@@@ -1,178 -1,0 +1,182 @@@
-                                          struct pipe_subresource subresource,
 +/**************************************************************************
 + * 
 + * Copyright 2009 Younes Manton.
 + * 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 TUNGSTEN GRAPHICS 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.
 + * 
 + **************************************************************************/
 +
 +#ifndef PIPE_VIDEO_CONTEXT_H
 +#define PIPE_VIDEO_CONTEXT_H
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif
 +
 +#include <pipe/p_video_state.h>
 +
 +/* XXX: Move to an appropriate place */
 +#define PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT 256
 +
 +struct pipe_screen;
 +struct pipe_buffer;
 +struct pipe_surface;
 +struct pipe_macroblock;
 +struct pipe_picture_desc;
 +struct pipe_fence_handle;
 +
 +/**
 + * Gallium video rendering context
 + */
 +struct pipe_video_context
 +{
 +   struct pipe_screen *screen;
 +   enum pipe_video_profile profile;
 +   enum pipe_video_chroma_format chroma_format;
 +   unsigned width;
 +   unsigned height;
 +
 +   void *priv; /**< context private data (for DRI for example) */
 +
 +   /**
 +    * Query an integer-valued capability/parameter/limit
 +    * \param param  one of PIPE_CAP_x
 +    */
 +   int (*get_param)(struct pipe_video_context *vpipe, int param);
 +
 +   /**
 +    * Check if the given pipe_format is supported as a texture or
 +    * drawing surface.
 +    */
 +   boolean (*is_format_supported)(struct pipe_video_context *vpipe,
 +                                  enum pipe_format format,
 +                                  unsigned usage,
 +                                  unsigned geom);
 +
 +   void (*destroy)(struct pipe_video_context *vpipe);
 +
++   struct pipe_surface *(*create_surface)(struct pipe_video_context *vpipe,
++                                          struct pipe_resource *resource,
++                                          const struct pipe_surface *templat);
++
 +   /**
 +    * Picture decoding and displaying
 +    */
 +   /*@{*/
 +   void (*decode_bitstream)(struct pipe_video_context *vpipe,
 +                            unsigned num_bufs,
 +                            struct pipe_buffer **bitstream_buf);
 +
 +   void (*decode_macroblocks)(struct pipe_video_context *vpipe,
 +                              struct pipe_surface *past,
 +                              struct pipe_surface *future,
 +                              unsigned num_macroblocks,
 +                              struct pipe_macroblock *macroblocks,
 +                              struct pipe_fence_handle **fence);
 +
 +   void (*render_picture)(struct pipe_video_context     *vpipe,
 +                          struct pipe_surface           *src_surface,
 +                          enum pipe_mpeg12_picture_type picture_type,
 +                          /*unsigned                    num_past_surfaces,
 +                          struct pipe_surface           *past_surfaces,
 +                          unsigned                      num_future_surfaces,
 +                          struct pipe_surface           *future_surfaces,*/
 +                          struct pipe_video_rect        *src_area,
 +                          struct pipe_surface           *dst_surface,
 +                          struct pipe_video_rect        *dst_area,
 +                          struct pipe_fence_handle      **fence);
 +
 +   void (*surface_fill)(struct pipe_video_context *vpipe,
 +                        struct pipe_surface *dst,
 +                        unsigned dstx, unsigned dsty,
 +                        unsigned width, unsigned height,
 +                        unsigned value);
 +
 +   void (*surface_copy)(struct pipe_video_context *vpipe,
 +                        struct pipe_surface *dst,
 +                        unsigned dstx, unsigned dsty,
 +                        struct pipe_surface *src,
 +                        unsigned srcx, unsigned srcy,
 +                        unsigned width, unsigned height);
 +
 +   struct pipe_transfer *(*get_transfer)(struct pipe_video_context *vpipe,
 +                                         struct pipe_resource *resource,
-                                  struct pipe_subresource subresource,
++                                         unsigned level,
 +                                         unsigned usage,  /* a combination of PIPE_TRANSFER_x */
 +                                         const struct pipe_box *box);
 +
 +   void (*transfer_destroy)(struct pipe_video_context *vpipe,
 +                            struct pipe_transfer *transfer);
 +
 +   void* (*transfer_map)(struct pipe_video_context *vpipe,
 +                         struct pipe_transfer *transfer);
 +
 +   void (*transfer_flush_region)(struct pipe_video_context *vpipe,
 +                                 struct pipe_transfer *transfer,
 +                                 const struct pipe_box *box);
 +
 +   void (*transfer_unmap)(struct pipe_video_context *vpipe,
 +                          struct pipe_transfer *transfer);
 +
 +   void (*transfer_inline_write)(struct pipe_video_context *vpipe,
 +                                 struct pipe_resource *resource,
++                                 unsigned level,
 +                                 unsigned usage, /* a combination of PIPE_TRANSFER_x */
 +                                 const struct pipe_box *box,
 +                                 const void *data,
 +                                 unsigned stride,
 +                                 unsigned slice_stride);
 +
 +   /*@}*/
 +
 +   /**
 +    * Parameter-like states (or properties)
 +    */
 +   /*@{*/
 +   void (*set_picture_background)(struct pipe_video_context *vpipe,
 +                                  struct pipe_surface *bg,
 +                                  struct pipe_video_rect *bg_src_rect);
 +
 +   void (*set_picture_layers)(struct pipe_video_context *vpipe,
 +                              struct pipe_surface *layers[],
 +                              struct pipe_video_rect *src_rects[],
 +                              struct pipe_video_rect *dst_rects[],
 +                              unsigned num_layers);
 +
 +   void (*set_picture_desc)(struct pipe_video_context *vpipe,
 +                            const struct pipe_picture_desc *desc);
 +
 +   void (*set_decode_target)(struct pipe_video_context *vpipe,
 +                             struct pipe_surface *dt);
 +
 +   void (*set_csc_matrix)(struct pipe_video_context *vpipe, const float *mat);
 +
 +   /* TODO: Interface for scaling modes, post-processing, etc. */
 +   /*@}*/
 +};
 +
 +
 +#ifdef __cplusplus
 +}
 +#endif
 +
 +#endif /* PIPE_VIDEO_CONTEXT_H */
index e0c9e303817a6b7a4891fc5a6ca15fd7fa5fb6e3,0000000000000000000000000000000000000000..1c70d1deb66808a903a7e68ce957460dcfc97d13
mode 100644,000000..100644
--- /dev/null
@@@ -1,440 -1,0 +1,443 @@@
-    subpicture_priv->sfc = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0,
-                                                          PIPE_BIND_SAMPLER_VIEW);
 +/**************************************************************************
 + *
 + * Copyright 2009 Younes Manton.
 + * 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 TUNGSTEN GRAPHICS 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 <assert.h>
 +#include <X11/Xlibint.h>
 +#include <X11/extensions/XvMClib.h>
 +#include <xorg/fourcc.h>
 +#include <vl_winsys.h>
 +#include <pipe/p_screen.h>
 +#include <pipe/p_video_context.h>
 +#include <pipe/p_state.h>
 +#include <util/u_memory.h>
 +#include <util/u_math.h>
 +#include "xvmc_private.h"
 +
 +#define FOURCC_RGB 0x0000003
 +
 +static enum pipe_format XvIDToPipe(int xvimage_id)
 +{
 +   switch (xvimage_id) {
 +      case FOURCC_RGB:
 +         return PIPE_FORMAT_B8G8R8X8_UNORM;
 +      default:
 +         XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized Xv image ID 0x%08X.\n", xvimage_id);
 +         return PIPE_FORMAT_NONE;
 +   }
 +}
 +
 +static int PipeToComponentOrder(enum pipe_format format, char *component_order)
 +{
 +   assert(component_order);
 +
 +   switch (format) {
 +      case PIPE_FORMAT_B8G8R8X8_UNORM:
 +         return 0;
 +      default:
 +         XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized PIPE_FORMAT 0x%08X.\n", format);
 +         component_order[0] = 0;
 +         component_order[1] = 0;
 +         component_order[2] = 0;
 +         component_order[3] = 0;
 +   }
 +
 +      return 0;
 +}
 +
 +static Status Validate(Display *dpy, XvPortID port, int surface_type_id, int xvimage_id)
 +{
 +   XvImageFormatValues *subpictures;
 +   int num_subpics;
 +   unsigned int i;
 +
 +   subpictures = XvMCListSubpictureTypes(dpy, port, surface_type_id, &num_subpics);
 +   if (num_subpics < 1) {
 +      if (subpictures)
 +         XFree(subpictures);
 +      return BadMatch;
 +   }
 +   if (!subpictures)
 +      return BadAlloc;
 +
 +   for (i = 0; i < num_subpics; ++i) {
 +      if (subpictures[i].id == xvimage_id) {
 +         XVMC_MSG(XVMC_TRACE, "[XvMC] Found requested subpicture format.\n" \
 +                              "[XvMC]   port=%u\n" \
 +                              "[XvMC]   surface id=0x%08X\n" \
 +                              "[XvMC]   image id=0x%08X\n" \
 +                              "[XvMC]   type=%08X\n" \
 +                              "[XvMC]   byte order=%08X\n" \
 +                              "[XvMC]   bits per pixel=%u\n" \
 +                              "[XvMC]   format=%08X\n" \
 +                              "[XvMC]   num planes=%d\n",
 +                              port, surface_type_id, xvimage_id, subpictures[i].type, subpictures[i].byte_order,
 +                              subpictures[i].bits_per_pixel, subpictures[i].format, subpictures[i].num_planes);
 +         if (subpictures[i].type == XvRGB) {
 +            XVMC_MSG(XVMC_TRACE, "[XvMC]   depth=%d\n" \
 +                                 "[XvMC]   red mask=0x%08X\n" \
 +                                 "[XvMC]   green mask=0x%08X\n" \
 +                                 "[XvMC]   blue mask=0x%08X\n",
 +                                 subpictures[i].depth, subpictures[i].red_mask, subpictures[i].green_mask, subpictures[i].blue_mask);
 +         }
 +         else if (subpictures[i].type == XvYUV) {
 +            XVMC_MSG(XVMC_TRACE, "[XvMC]   y sample bits=0x%08X\n" \
 +                                 "[XvMC]   u sample bits=0x%08X\n" \
 +                                 "[XvMC]   v sample bits=0x%08X\n" \
 +                                 "[XvMC]   horz y period=%u\n" \
 +                                 "[XvMC]   horz u period=%u\n" \
 +                                 "[XvMC]   horz v period=%u\n" \
 +                                 "[XvMC]   vert y period=%u\n" \
 +                                 "[XvMC]   vert u period=%u\n" \
 +                                 "[XvMC]   vert v period=%u\n",
 +                                 subpictures[i].y_sample_bits, subpictures[i].u_sample_bits, subpictures[i].v_sample_bits,
 +                                 subpictures[i].horz_y_period, subpictures[i].horz_u_period, subpictures[i].horz_v_period,
 +                                 subpictures[i].vert_y_period, subpictures[i].vert_u_period, subpictures[i].vert_v_period);
 +         }
 +         break;
 +      }
 +   }
 +
 +   XFree(subpictures);
 +
 +   return i < num_subpics ? Success : BadMatch;
 +}
 +
 +PUBLIC
 +Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture *subpicture,
 +                            unsigned short width, unsigned short height, int xvimage_id)
 +{
 +   XvMCContextPrivate *context_priv;
 +   XvMCSubpicturePrivate *subpicture_priv;
 +   struct pipe_video_context *vpipe;
 +   struct pipe_resource template;
 +   struct pipe_resource *tex;
++   struct pipe_surface surf_template;
 +   Status ret;
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Creating subpicture %p.\n", subpicture);
 +
 +   assert(dpy);
 +
 +   if (!context)
 +      return XvMCBadContext;
 +
 +   context_priv = context->privData;
 +   vpipe = context_priv->vctx->vpipe;
 +
 +   if (!subpicture)
 +      return XvMCBadSubpicture;
 +
 +   if (width > context_priv->subpicture_max_width ||
 +       height > context_priv->subpicture_max_height)
 +      return BadValue;
 +
 +   ret = Validate(dpy, context->port, context->surface_type_id, xvimage_id);
 +   if (ret != Success)
 +      return ret;
 +
 +   subpicture_priv = CALLOC(1, sizeof(XvMCSubpicturePrivate));
 +   if (!subpicture_priv)
 +      return BadAlloc;
 +
 +   memset(&template, 0, sizeof(struct pipe_resource));
 +   template.target = PIPE_TEXTURE_2D;
 +   template.format = XvIDToPipe(xvimage_id);
 +   template.last_level = 0;
 +   if (vpipe->get_param(vpipe, PIPE_CAP_NPOT_TEXTURES)) {
 +      template.width0 = width;
 +      template.height0 = height;
 +   }
 +   else {
 +      template.width0 = util_next_power_of_two(width);
 +      template.height0 = util_next_power_of_two(height);
 +   }
 +   template.depth0 = 1;
 +   template.usage = PIPE_USAGE_DYNAMIC;
 +   template.bind = PIPE_BIND_SAMPLER_VIEW;
 +   template.flags = 0;
 +
 +   subpicture_priv->context = context;
 +   tex = vpipe->screen->resource_create(vpipe->screen, &template);
-    struct pipe_subresource sr = {0, 0};
++
++   memset(&surf_template, 0, sizeof(surf_template));
++   surf_template.format = tex->format;
++   surf_template.usage = PIPE_BIND_SAMPLER_VIEW;
++   subpicture_priv->sfc = vpipe->create_surface(vpipe, tex, &surf_template);
 +   pipe_resource_reference(&tex, NULL);
 +   if (!subpicture_priv->sfc) {
 +      FREE(subpicture_priv);
 +      return BadAlloc;
 +   }
 +
 +   subpicture->subpicture_id = XAllocID(dpy);
 +   subpicture->context_id = context->context_id;
 +   subpicture->xvimage_id = xvimage_id;
 +   subpicture->width = width;
 +   subpicture->height = height;
 +   subpicture->num_palette_entries = 0;
 +   subpicture->entry_bytes = PipeToComponentOrder(template.format, subpicture->component_order);
 +   subpicture->privData = subpicture_priv;
 +
 +   SyncHandle();
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Subpicture %p created.\n", subpicture);
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCClearSubpicture(Display *dpy, XvMCSubpicture *subpicture, short x, short y,
 +                           unsigned short width, unsigned short height, unsigned int color)
 +{
 +   XvMCSubpicturePrivate *subpicture_priv;
 +   XvMCContextPrivate *context_priv;
 +
 +   assert(dpy);
 +
 +   if (!subpicture)
 +      return XvMCBadSubpicture;
 +
 +   subpicture_priv = subpicture->privData;
 +   context_priv = subpicture_priv->context->privData;
 +   /* TODO: Assert clear rect is within bounds? Or clip? */
 +   context_priv->vctx->vpipe->surface_fill(context_priv->vctx->vpipe,
 +                                           subpicture_priv->sfc, x, y,
 +                                           width, height, color);
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCCompositeSubpicture(Display *dpy, XvMCSubpicture *subpicture, XvImage *image,
 +                               short srcx, short srcy, unsigned short width, unsigned short height,
 +                               short dstx, short dsty)
 +{
 +   XvMCSubpicturePrivate *subpicture_priv;
 +   XvMCContextPrivate *context_priv;
 +   struct pipe_video_context *vpipe;
 +   struct pipe_transfer *xfer;
 +   unsigned char *src, *dst, *dst_line;
 +   unsigned x, y;
 +   struct pipe_box dst_box = {dstx, dsty, 0, width, height, 1};
-                               sr, PIPE_TRANSFER_WRITE, &dst_box);
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Compositing subpicture %p.\n", subpicture);
 +
 +   assert(dpy);
 +
 +   if (!subpicture)
 +      return XvMCBadSubpicture;
 +
 +   assert(image);
 +
 +   if (subpicture->xvimage_id != image->id)
 +      return BadMatch;
 +
 +   /* No planar support for now */
 +   if (image->num_planes != 1)
 +      return BadMatch;
 +
 +   subpicture_priv = subpicture->privData;
 +   context_priv = subpicture_priv->context->privData;
 +   vpipe = context_priv->vctx->vpipe;
 +
 +   /* TODO: Assert rects are within bounds? Or clip? */
 +
 +   xfer = vpipe->get_transfer(vpipe, subpicture_priv->sfc->texture,
++                              0, PIPE_TRANSFER_WRITE, &dst_box);
 +   if (!xfer)
 +      return BadAlloc;
 +
 +   src = image->data;
 +   dst = vpipe->transfer_map(vpipe, xfer);
 +   if (!dst) {
 +      vpipe->transfer_destroy(vpipe, xfer);
 +      return BadAlloc;
 +   }
 +
 +   switch (image->id) {
 +      case FOURCC_RGB:
 +         assert(subpicture_priv->sfc->format == XvIDToPipe(image->id));
 +         for (y = 0; y < height; ++y) {
 +            dst_line = dst;
 +            for (x = 0; x < width; ++x, src += 3, dst_line += 4) {
 +               dst_line[0] = src[2]; /* B */
 +               dst_line[1] = src[1]; /* G */
 +               dst_line[2] = src[0]; /* R */
 +            }
 +            dst += xfer->stride;
 +         }
 +         break;
 +      default:
 +         XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized Xv image ID 0x%08X.\n", image->id);
 +   }
 +
 +   vpipe->transfer_unmap(vpipe, xfer);
 +   vpipe->transfer_destroy(vpipe, xfer);
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Subpicture %p composited.\n", subpicture);
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCDestroySubpicture(Display *dpy, XvMCSubpicture *subpicture)
 +{
 +   XvMCSubpicturePrivate *subpicture_priv;
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying subpicture %p.\n", subpicture);
 +
 +   assert(dpy);
 +
 +   if (!subpicture)
 +      return XvMCBadSubpicture;
 +
 +   subpicture_priv = subpicture->privData;
 +   pipe_surface_reference(&subpicture_priv->sfc, NULL);
 +   FREE(subpicture_priv);
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Subpicture %p destroyed.\n", subpicture);
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCSetSubpicturePalette(Display *dpy, XvMCSubpicture *subpicture, unsigned char *palette)
 +{
 +   assert(dpy);
 +
 +   if (!subpicture)
 +      return XvMCBadSubpicture;
 +
 +   assert(palette);
 +
 +   /* We don't support paletted subpictures */
 +   return BadMatch;
 +}
 +
 +PUBLIC
 +Status XvMCBlendSubpicture(Display *dpy, XvMCSurface *target_surface, XvMCSubpicture *subpicture,
 +                           short subx, short suby, unsigned short subw, unsigned short subh,
 +                           short surfx, short surfy, unsigned short surfw, unsigned short surfh)
 +{
 +   XvMCSurfacePrivate *surface_priv;
 +   XvMCSubpicturePrivate *subpicture_priv;
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Associating subpicture %p with surface %p.\n", subpicture, target_surface);
 +
 +   assert(dpy);
 +
 +   if (!target_surface)
 +      return XvMCBadSurface;
 +
 +   if (!subpicture)
 +      return XvMCBadSubpicture;
 +
 +   if (target_surface->context_id != subpicture->context_id)
 +      return BadMatch;
 +
 +   /* TODO: Verify against subpicture independent scaling */
 +
 +   surface_priv = target_surface->privData;
 +   subpicture_priv = subpicture->privData;
 +
 +   /* TODO: Assert rects are within bounds? Or clip? */
 +
 +   surface_priv->subpicture = subpicture;
 +   surface_priv->subx = subx;
 +   surface_priv->suby = suby;
 +   surface_priv->subw = subw;
 +   surface_priv->subh = subh;
 +   surface_priv->surfx = surfx;
 +   surface_priv->surfy = surfy;
 +   surface_priv->surfw = surfw;
 +   surface_priv->surfh = surfh;
 +   subpicture_priv->surface = target_surface;
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCBlendSubpicture2(Display *dpy, XvMCSurface *source_surface, XvMCSurface *target_surface,
 +                            XvMCSubpicture *subpicture, short subx, short suby, unsigned short subw, unsigned short subh,
 +                            short surfx, short surfy, unsigned short surfw, unsigned short surfh)
 +{
 +   assert(dpy);
 +
 +   if (!source_surface || !target_surface)
 +      return XvMCBadSurface;
 +
 +   if (!subpicture)
 +      return XvMCBadSubpicture;
 +
 +   if (source_surface->context_id != subpicture->context_id)
 +      return BadMatch;
 +
 +   if (source_surface->context_id != subpicture->context_id)
 +      return BadMatch;
 +
 +   /* TODO: Assert rects are within bounds? Or clip? */
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCSyncSubpicture(Display *dpy, XvMCSubpicture *subpicture)
 +{
 +   assert(dpy);
 +
 +   if (!subpicture)
 +      return XvMCBadSubpicture;
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCFlushSubpicture(Display *dpy, XvMCSubpicture *subpicture)
 +{
 +   assert(dpy);
 +
 +   if (!subpicture)
 +      return XvMCBadSubpicture;
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCGetSubpictureStatus(Display *dpy, XvMCSubpicture *subpicture, int *status)
 +{
 +   assert(dpy);
 +
 +   if (!subpicture)
 +      return XvMCBadSubpicture;
 +
 +   assert(status);
 +
 +   /* TODO */
 +   *status = 0;
 +
 +   return Success;
 +}
index 209dffd2c58e7dfd439113130681789a35c56285,0000000000000000000000000000000000000000..d7285a478fb4e473663cb0060e4b52dadf76d6b6
mode 100644,000000..100644
--- /dev/null
@@@ -1,521 -1,0 +1,525 @@@
-    vsfc = vpipe->screen->get_tex_surface(vpipe->screen, vsfc_tex, 0, 0, 0,
-                                          PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET);
 +/**************************************************************************
 + *
 + * Copyright 2009 Younes Manton.
 + * 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 TUNGSTEN GRAPHICS 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 <assert.h>
 +#include <stdio.h>
 +#include <X11/Xlibint.h>
 +#include <vl_winsys.h>
 +#include <pipe/p_video_context.h>
 +#include <pipe/p_video_state.h>
 +#include <pipe/p_state.h>
 +#include <util/u_inlines.h>
 +#include <util/u_memory.h>
 +#include <util/u_math.h>
 +#include "xvmc_private.h"
 +
 +static enum pipe_mpeg12_macroblock_type TypeToPipe(int xvmc_mb_type)
 +{
 +   if (xvmc_mb_type & XVMC_MB_TYPE_INTRA)
 +      return PIPE_MPEG12_MACROBLOCK_TYPE_INTRA;
 +   if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_FORWARD)
 +      return PIPE_MPEG12_MACROBLOCK_TYPE_FWD;
 +   if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_BACKWARD)
 +      return PIPE_MPEG12_MACROBLOCK_TYPE_BKWD;
 +   if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD))
 +      return PIPE_MPEG12_MACROBLOCK_TYPE_BI;
 +
 +   assert(0);
 +
 +   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized mb type 0x%08X.\n", xvmc_mb_type);
 +
 +   return -1;
 +}
 +
 +static enum pipe_mpeg12_picture_type PictureToPipe(int xvmc_pic)
 +{
 +   switch (xvmc_pic) {
 +      case XVMC_TOP_FIELD:
 +         return PIPE_MPEG12_PICTURE_TYPE_FIELD_TOP;
 +      case XVMC_BOTTOM_FIELD:
 +         return PIPE_MPEG12_PICTURE_TYPE_FIELD_BOTTOM;
 +      case XVMC_FRAME_PICTURE:
 +         return PIPE_MPEG12_PICTURE_TYPE_FRAME;
 +      default:
 +         assert(0);
 +   }
 +
 +   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized picture type 0x%08X.\n", xvmc_pic);
 +
 +   return -1;
 +}
 +
 +static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, unsigned int xvmc_picture_structure)
 +{
 +   switch (xvmc_motion_type) {
 +      case XVMC_PREDICTION_FRAME:
 +         if (xvmc_picture_structure == XVMC_FRAME_PICTURE)
 +            return PIPE_MPEG12_MOTION_TYPE_FRAME;
 +         else
 +            return PIPE_MPEG12_MOTION_TYPE_16x8;
 +         break;
 +      case XVMC_PREDICTION_FIELD:
 +         return PIPE_MPEG12_MOTION_TYPE_FIELD;
 +      case XVMC_PREDICTION_DUAL_PRIME:
 +         return PIPE_MPEG12_MOTION_TYPE_DUALPRIME;
 +      default:
 +         assert(0);
 +   }
 +
 +   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized motion type 0x%08X (with picture structure 0x%08X).\n", xvmc_motion_type, xvmc_picture_structure);
 +
 +   return -1;
 +}
 +
 +#if 0
 +static bool
 +CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned int height,
 +                         struct pipe_surface **backbuffer)
 +{
 +   struct pipe_video_context *vpipe;
 +   struct pipe_resource template;
 +   struct pipe_resource *tex;
 +
 +   assert(vctx);
 +
 +   vpipe = vctx->vpipe;
 +
 +   if (*backbuffer) {
 +      if ((*backbuffer)->width != width || (*backbuffer)->height != height)
 +         pipe_surface_reference(backbuffer, NULL);
 +      else
 +         return true;
 +   }
 +
 +   memset(&template, 0, sizeof(struct pipe_resource));
 +   template.target = PIPE_TEXTURE_2D;
 +   template.format = vctx->vscreen->format;
 +   template.last_level = 0;
 +   template.width0 = width;
 +   template.height0 = height;
 +   template.depth0 = 1;
 +   template.usage = PIPE_USAGE_DEFAULT;
 +   template.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_BLIT_SOURCE;
 +   template.flags = 0;
 +
 +   tex = vpipe->screen->resource_create(vpipe->screen, &template);
 +   if (!tex)
 +      return false;
 +
 +   *backbuffer = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0,
 +                                                template.bind);
 +   pipe_resource_reference(&tex, NULL);
 +
 +   if (!*backbuffer)
 +      return false;
 +
 +   /* Clear the backbuffer in case the video doesn't cover the whole window */
 +   /* FIXME: Need to clear every time a frame moves and leaves dirty rects */
 +   vpipe->surface_fill(vpipe, *backbuffer, 0, 0, width, height, 0);
 +
 +   return true;
 +}
 +#endif
 +
 +static void
 +MacroBlocksToPipe(struct pipe_screen *screen,
 +                  unsigned int xvmc_picture_structure,
 +                  const XvMCMacroBlockArray *xvmc_macroblocks,
 +                  const XvMCBlockArray *xvmc_blocks,
 +                  unsigned int first_macroblock,
 +                  unsigned int num_macroblocks,
 +                  struct pipe_mpeg12_macroblock *pipe_macroblocks)
 +{
 +   unsigned int i, j, k, l;
 +   XvMCMacroBlock *xvmc_mb;
 +
 +   assert(xvmc_macroblocks);
 +   assert(xvmc_blocks);
 +   assert(pipe_macroblocks);
 +   assert(num_macroblocks);
 +
 +   xvmc_mb = xvmc_macroblocks->macro_blocks + first_macroblock;
 +
 +   for (i = 0; i < num_macroblocks; ++i) {
 +      pipe_macroblocks->base.codec = PIPE_VIDEO_CODEC_MPEG12;
 +      pipe_macroblocks->mbx = xvmc_mb->x;
 +      pipe_macroblocks->mby = xvmc_mb->y;
 +      pipe_macroblocks->mb_type = TypeToPipe(xvmc_mb->macroblock_type);
 +      if (pipe_macroblocks->mb_type != PIPE_MPEG12_MACROBLOCK_TYPE_INTRA)
 +         pipe_macroblocks->mo_type = MotionToPipe(xvmc_mb->motion_type, xvmc_picture_structure);
 +      /* Get rid of Valgrind 'undefined' warnings */
 +      else
 +         pipe_macroblocks->mo_type = -1;
 +      pipe_macroblocks->dct_type = xvmc_mb->dct_type == XVMC_DCT_TYPE_FIELD ?
 +         PIPE_MPEG12_DCT_TYPE_FIELD : PIPE_MPEG12_DCT_TYPE_FRAME;
 +
 +      for (j = 0; j < 2; ++j)
 +         for (k = 0; k < 2; ++k)
 +            for (l = 0; l < 2; ++l)
 +               pipe_macroblocks->pmv[j][k][l] = xvmc_mb->PMV[j][k][l];
 +
 +      pipe_macroblocks->mvfs[0][0] = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD;
 +      pipe_macroblocks->mvfs[0][1] = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_FIRST_BACKWARD;
 +      pipe_macroblocks->mvfs[1][0] = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_SECOND_FORWARD;
 +      pipe_macroblocks->mvfs[1][1] = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_SECOND_BACKWARD;
 +
 +      pipe_macroblocks->cbp = xvmc_mb->coded_block_pattern;
 +      pipe_macroblocks->blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
 +
 +      ++pipe_macroblocks;
 +      ++xvmc_mb;
 +   }
 +}
 +
 +PUBLIC
 +Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surface)
 +{
 +   XvMCContextPrivate *context_priv;
 +   struct pipe_video_context *vpipe;
 +   XvMCSurfacePrivate *surface_priv;
 +   struct pipe_resource template;
 +   struct pipe_resource *vsfc_tex;
++   struct pipe_surface surf_template;
 +   struct pipe_surface *vsfc;
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Creating surface %p.\n", surface);
 +
 +   assert(dpy);
 +
 +   if (!context)
 +      return XvMCBadContext;
 +   if (!surface)
 +      return XvMCBadSurface;
 +
 +   context_priv = context->privData;
 +   vpipe = context_priv->vctx->vpipe;
 +
 +   surface_priv = CALLOC(1, sizeof(XvMCSurfacePrivate));
 +   if (!surface_priv)
 +      return BadAlloc;
 +
 +   memset(&template, 0, sizeof(struct pipe_resource));
 +   template.target = PIPE_TEXTURE_2D;
 +   template.format = (enum pipe_format)vpipe->get_param(vpipe, PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT);
 +   template.last_level = 0;
 +   if (vpipe->is_format_supported(vpipe, template.format,
 +                                  PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
 +                                  PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)) {
 +      template.width0 = context->width;
 +      template.height0 = context->height;
 +   }
 +   else {
 +      assert(vpipe->is_format_supported(vpipe, template.format,
 +                                       PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
 +                                       PIPE_TEXTURE_GEOM_NON_SQUARE));
 +      template.width0 = util_next_power_of_two(context->width);
 +      template.height0 = util_next_power_of_two(context->height);
 +   }
 +   template.depth0 = 1;
 +   template.usage = PIPE_USAGE_DEFAULT;
 +   template.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
 +   template.flags = 0;
 +   vsfc_tex = vpipe->screen->resource_create(vpipe->screen, &template);
 +   if (!vsfc_tex) {
 +      FREE(surface_priv);
 +      return BadAlloc;
 +   }
 +
-    drawable_surface = vl_drawable_surface_get(context_priv->vctx->vscreen, drawable);
++   memset(&surf_template, 0, sizeof(surf_template));
++   surf_template.format = vsfc_tex->format;
++   surf_template.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
++   vsfc = vpipe->create_surface(vpipe, vsfc_tex, &surf_template);
 +   pipe_resource_reference(&vsfc_tex, NULL);
 +   if (!vsfc) {
 +      FREE(surface_priv);
 +      return BadAlloc;
 +   }
 +
 +   surface_priv->pipe_vsfc = vsfc;
 +   surface_priv->context = context;
 +
 +   surface->surface_id = XAllocID(dpy);
 +   surface->context_id = context->context_id;
 +   surface->surface_type_id = context->surface_type_id;
 +   surface->width = context->width;
 +   surface->height = context->height;
 +   surface->privData = surface_priv;
 +
 +   SyncHandle();
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p created.\n", surface);
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int picture_structure,
 +                         XvMCSurface *target_surface, XvMCSurface *past_surface, XvMCSurface *future_surface,
 +                         unsigned int flags, unsigned int num_macroblocks, unsigned int first_macroblock,
 +                         XvMCMacroBlockArray *macroblocks, XvMCBlockArray *blocks
 +)
 +{
 +   struct pipe_video_context *vpipe;
 +   struct pipe_surface *t_vsfc;
 +   struct pipe_surface *p_vsfc;
 +   struct pipe_surface *f_vsfc;
 +   XvMCContextPrivate *context_priv;
 +   XvMCSurfacePrivate *target_surface_priv;
 +   XvMCSurfacePrivate *past_surface_priv;
 +   XvMCSurfacePrivate *future_surface_priv;
 +   struct pipe_mpeg12_macroblock pipe_macroblocks[num_macroblocks];
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Rendering to surface %p.\n", target_surface);
 +
 +   assert(dpy);
 +
 +   if (!context || !context->privData)
 +      return XvMCBadContext;
 +   if (!target_surface || !target_surface->privData)
 +      return XvMCBadSurface;
 +
 +   if (picture_structure != XVMC_TOP_FIELD &&
 +       picture_structure != XVMC_BOTTOM_FIELD &&
 +       picture_structure != XVMC_FRAME_PICTURE)
 +      return BadValue;
 +   /* Bkwd pred equivalent to fwd (past && !future) */
 +   if (future_surface && !past_surface)
 +      return BadMatch;
 +
 +   assert(context->context_id == target_surface->context_id);
 +   assert(!past_surface || context->context_id == past_surface->context_id);
 +   assert(!future_surface || context->context_id == future_surface->context_id);
 +
 +   assert(macroblocks);
 +   assert(blocks);
 +
 +   assert(macroblocks->context_id == context->context_id);
 +   assert(blocks->context_id == context->context_id);
 +
 +   assert(flags == 0 || flags == XVMC_SECOND_FIELD);
 +
 +   target_surface_priv = target_surface->privData;
 +   past_surface_priv = past_surface ? past_surface->privData : NULL;
 +   future_surface_priv = future_surface ? future_surface->privData : NULL;
 +
 +   assert(target_surface_priv->context == context);
 +   assert(!past_surface || past_surface_priv->context == context);
 +   assert(!future_surface || future_surface_priv->context == context);
 +
 +   context_priv = context->privData;
 +   vpipe = context_priv->vctx->vpipe;
 +
 +   t_vsfc = target_surface_priv->pipe_vsfc;
 +   p_vsfc = past_surface ? past_surface_priv->pipe_vsfc : NULL;
 +   f_vsfc = future_surface ? future_surface_priv->pipe_vsfc : NULL;
 +
 +   MacroBlocksToPipe(vpipe->screen, picture_structure, macroblocks, blocks, first_macroblock,
 +                     num_macroblocks, pipe_macroblocks);
 +
 +   vpipe->set_decode_target(vpipe, t_vsfc);
 +   vpipe->decode_macroblocks(vpipe, p_vsfc, f_vsfc, num_macroblocks,
 +                             &pipe_macroblocks->base, &target_surface_priv->render_fence);
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCFlushSurface(Display *dpy, XvMCSurface *surface)
 +{
 +   assert(dpy);
 +
 +   if (!surface)
 +      return XvMCBadSurface;
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCSyncSurface(Display *dpy, XvMCSurface *surface)
 +{
 +   assert(dpy);
 +
 +   if (!surface)
 +      return XvMCBadSurface;
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
 +                      short srcx, short srcy, unsigned short srcw, unsigned short srch,
 +                      short destx, short desty, unsigned short destw, unsigned short desth,
 +                      int flags)
 +{
 +   static int dump_window = -1;
 +
 +   struct pipe_video_context *vpipe;
 +   XvMCSurfacePrivate *surface_priv;
 +   XvMCContextPrivate *context_priv;
 +   XvMCSubpicturePrivate *subpicture_priv;
 +   XvMCContext *context;
 +   struct pipe_video_rect src_rect = {srcx, srcy, srcw, srch};
 +   struct pipe_video_rect dst_rect = {destx, desty, destw, desth};
 +   struct pipe_surface *drawable_surface;
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Displaying surface %p.\n", surface);
 +
 +   assert(dpy);
 +
 +   if (!surface || !surface->privData)
 +      return XvMCBadSurface;
 +
 +   surface_priv = surface->privData;
 +   context = surface_priv->context;
 +   context_priv = context->privData;
 +
-       drawable_surface,
++   drawable_surface = vl_drawable_surface_get(context_priv->vctx, drawable);
 +   if (!drawable_surface)
 +      return BadDrawable;
 +
 +   assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE);
 +   assert(srcx + srcw - 1 < surface->width);
 +   assert(srcy + srch - 1 < surface->height);
 +   /*
 +    * Some apps (mplayer) hit these asserts because they call
 +    * this function after the window has been resized by the WM
 +    * but before they've handled the corresponding XEvent and
 +    * know about the new dimensions. The output should be clipped
 +    * until the app updates destw and desth.
 +    */
 +   /*
 +   assert(destx + destw - 1 < drawable_surface->width);
 +   assert(desty + desth - 1 < drawable_surface->height);
 +    */
 +
 +   subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL;
 +   vpipe = context_priv->vctx->vpipe;
 +
 +#if 0
 +   if (!CreateOrResizeBackBuffer(context_priv->vctx, width, height, &context_priv->backbuffer))
 +      return BadAlloc;
 +#endif
 +
 +   if (subpicture_priv) {
 +      struct pipe_video_rect src_rect = {surface_priv->subx, surface_priv->suby, surface_priv->subw, surface_priv->subh};
 +      struct pipe_video_rect dst_rect = {surface_priv->surfx, surface_priv->surfy, surface_priv->surfw, surface_priv->surfh};
 +      struct pipe_video_rect *src_rects[1] = {&src_rect};
 +      struct pipe_video_rect *dst_rects[1] = {&dst_rect};
 +
 +      XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture);
 +
 +      assert(subpicture_priv->surface == surface);
 +      vpipe->set_picture_layers(vpipe, &subpicture_priv->sfc, src_rects, dst_rects, 1);
 +
 +      surface_priv->subpicture = NULL;
 +      subpicture_priv->surface = NULL;
 +   }
 +   else
 +      vpipe->set_picture_layers(vpipe, NULL, NULL, NULL, 0);
 +
 +   vpipe->render_picture(vpipe, surface_priv->pipe_vsfc, PictureToPipe(flags), &src_rect,
 +                         drawable_surface, &dst_rect, &surface_priv->disp_fence);
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface);
 +
 +   vpipe->screen->flush_frontbuffer
 +   (
 +      vpipe->screen,
++      drawable_surface->texture,
++      0, 0,
 +      vl_contextprivate_get(context_priv->vctx, drawable_surface)
 +   );
 +
 +   pipe_surface_reference(&drawable_surface, NULL);
 +
 +   if(dump_window == -1) {
 +      dump_window = debug_get_num_option("XVMC_DUMP", 0);
 +   }
 +
 +   if(dump_window) {
 +      static unsigned int framenum = 0;
 +      char cmd[256];
 +      sprintf(cmd, "xwd -id %d -out xvmc_frame_%08d.xwd", (int)drawable, ++framenum);
 +      system(cmd);
 +   }
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Pushed surface %p to front buffer.\n", surface);
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCGetSurfaceStatus(Display *dpy, XvMCSurface *surface, int *status)
 +{
 +   assert(dpy);
 +
 +   if (!surface)
 +      return XvMCBadSurface;
 +
 +   assert(status);
 +
 +   *status = 0;
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCDestroySurface(Display *dpy, XvMCSurface *surface)
 +{
 +   XvMCSurfacePrivate *surface_priv;
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying surface %p.\n", surface);
 +
 +   assert(dpy);
 +
 +   if (!surface || !surface->privData)
 +      return XvMCBadSurface;
 +
 +   surface_priv = surface->privData;
 +   pipe_surface_reference(&surface_priv->pipe_vsfc, NULL);
 +   FREE(surface_priv);
 +   surface->privData = NULL;
 +
 +   XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p destroyed.\n", surface);
 +
 +   return Success;
 +}
 +
 +PUBLIC
 +Status XvMCHideSurface(Display *dpy, XvMCSurface *surface)
 +{
 +   assert(dpy);
 +
 +   if (!surface || !surface->privData)
 +      return XvMCBadSurface;
 +
 +   /* No op, only for overlaid rendering */
 +
 +   return Success;
 +}
index 4d10e27c5806d34b1f0cd204f9dbff989214b6ec,0000000000000000000000000000000000000000..8588ddd17cbb3649c1c25cebf3e98f132b7f2657
mode 100644,000000..100644
--- /dev/null
@@@ -1,273 -1,0 +1,282 @@@
- vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
 +/**************************************************************************
 + *
 + * Copyright 2009 Younes Manton.
 + * 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 TUNGSTEN GRAPHICS 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 <vl_winsys.h>
 +#include <driclient.h>
 +#include <pipe/p_video_context.h>
 +#include <pipe/p_state.h>
 +#include <util/u_memory.h>
 +#include <util/u_hash.h>
 +#include <util/u_hash_table.h>
 +#include <state_tracker/drm_driver.h>
 +#include <X11/Xlibint.h>
 +
 +struct vl_dri_screen
 +{
 +   struct vl_screen base;
 +   dri_screen_t *dri_screen;
 +   struct util_hash_table *drawable_table;
 +   Drawable last_seen_drawable;
 +};
 +
 +struct vl_dri_context
 +{
 +   struct vl_context base;
 +   int fd;
 +};
 +
 +static struct pipe_surface*
-       if (front_tex)
-          front_surf = vl_dri_scrn->base.pscreen->get_tex_surface(vl_dri_scrn->base.pscreen,
-                                                                  front_tex, 0, 0, 0,
-                                                                  PIPE_BIND_RENDER_TARGET);
++vl_dri2_get_front(struct vl_context *vctx, Drawable drawable)
 +{
 +   int w, h;
 +   unsigned int attachments[1] = {DRI_BUFFER_FRONT_LEFT};
 +   int count;
 +   DRI2Buffer *dri2_front;
 +   struct pipe_resource *front_tex;
 +   struct pipe_surface *front_surf = NULL;
 +
++   assert(vctx);
++
++   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vctx->vscreen;
 +   assert(vl_dri_scrn);
 +
 +   dri2_front = DRI2GetBuffers(vl_dri_scrn->dri_screen->display,
 +                               drawable, &w, &h, attachments, 1, &count);
 +
 +   assert(count == 1);
 +
 +   if (dri2_front) {
 +      struct winsys_handle dri2_front_handle =
 +      {
 +         .type = DRM_API_HANDLE_TYPE_SHARED,
 +         .handle = dri2_front->name,
 +         .stride = dri2_front->pitch
 +      };
 +      struct pipe_resource template;
++      struct pipe_surface surf_template;
 +
 +      memset(&template, 0, sizeof(struct pipe_resource));
 +      template.target = PIPE_TEXTURE_2D;
 +      template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
 +      template.last_level = 0;
 +      template.width0 = w;
 +      template.height0 = h;
 +      template.depth0 = 1;
 +      template.usage = PIPE_USAGE_STATIC;
 +      template.bind = PIPE_BIND_RENDER_TARGET;
 +      template.flags = 0;
 +
 +      front_tex = vl_dri_scrn->base.pscreen->resource_from_handle(vl_dri_scrn->base.pscreen, &template, &dri2_front_handle);
-                           struct pipe_surface *surf, void *context_private)
++      if (front_tex) {
++         memset(&surf_template, 0, sizeof(surf_template));
++         surf_template.format = front_tex->format;
++         surf_template.usage = PIPE_BIND_RENDER_TARGET;
++         front_surf = vctx->vpipe->create_surface(vctx->vpipe, front_tex, &surf_template);
++      }
 +      pipe_resource_reference(&front_tex, NULL);
 +      Xfree(dri2_front);
 +   }
 +
 +   return front_surf;
 +}
 +
 +static void
 +vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
-    assert(surf);
++                          struct pipe_resource *resource,
++                          unsigned level, unsigned layer,
++                          void *context_private)
 +{
 +   struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)context_private;
 +   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen;
 +
 +   assert(screen);
- vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable)
++   assert(resource);
 +   assert(context_private);
 +
 +   dri2CopyDrawable(vl_dri_scrn->dri_screen, vl_dri_scrn->last_seen_drawable,
 +                    DRI_BUFFER_FRONT_LEFT, DRI_BUFFER_FAKE_FRONT_LEFT);
 +}
 +
 +struct pipe_surface*
-    struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen;
++vl_drawable_surface_get(struct vl_context *vctx, Drawable drawable)
 +{
-    assert(vscreen);
++   assert(vctx);
 +
-    return vl_dri2_get_front(vl_dri_scrn, drawable);
++   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vctx->vscreen;
++   assert(vl_dri_scrn);
 +
 +   if (vl_dri_scrn->last_seen_drawable != drawable) {
 +      /* Hash table business depends on this equality */
 +      assert(None == NULL);
 +      Drawable lookup_drawable = (Drawable)util_hash_table_get(vl_dri_scrn->drawable_table, (void*)drawable);
 +      if (lookup_drawable == None) {
 +         dri2CreateDrawable(vl_dri_scrn->dri_screen, drawable);
 +         util_hash_table_set(vl_dri_scrn->drawable_table, (void*)drawable, (void*)drawable);
 +      }
 +      vl_dri_scrn->last_seen_drawable = drawable;
 +   }
 +
++   return vl_dri2_get_front(vctx, drawable);
 +}
 +
 +void*
 +vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *displaytarget)
 +{
 +   return vctx;
 +}
 +
 +static unsigned drawable_hash(void *key)
 +{
 +   Drawable drawable = (Drawable)key;
 +   assert(drawable != None);
 +   return util_hash_crc32(&drawable, sizeof(Drawable));
 +}
 +
 +static int drawable_cmp(void *key1, void *key2)
 +{
 +   Drawable d1 = (Drawable)key1;
 +   Drawable d2 = (Drawable)key2;
 +   assert(d1 != None);
 +   assert(d2 != None);
 +   return d1 != d2;
 +}
 +
 +static enum pipe_error
 +drawable_destroy(void *key, void *value, void *data)
 +{
 +   Drawable drawable = (Drawable)key;
 +   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)data;
 +
 +   assert(drawable != None);
 +   assert(value);
 +   assert(data);
 +
 +   dri2DestroyDrawable(vl_dri_scrn->dri_screen, drawable);
 +
 +   return PIPE_OK;
 +}
 +
 +struct vl_screen*
 +vl_screen_create(Display *display, int screen)
 +{
 +   struct vl_dri_screen *vl_dri_scrn;
 +
 +   assert(display);
 +
 +   vl_dri_scrn = CALLOC_STRUCT(vl_dri_screen);
 +   if (!vl_dri_scrn)
 +      goto no_struct;
 +
 +   if (dri2CreateScreen(display, screen, &vl_dri_scrn->dri_screen))
 +      goto no_dri2screen;
 +
 +   vl_dri_scrn->base.pscreen = driver_descriptor.create_screen(vl_dri_scrn->dri_screen->fd);
 +
 +   if (!vl_dri_scrn->base.pscreen)
 +      goto no_pscreen;
 +
 +   vl_dri_scrn->drawable_table = util_hash_table_create(&drawable_hash, &drawable_cmp);
 +   if (!vl_dri_scrn->drawable_table)
 +      goto no_hash;
 +
 +   vl_dri_scrn->last_seen_drawable = None;
 +   vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer;
 +
 +   return &vl_dri_scrn->base;
 +
 +no_hash:
 +   vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen);
 +no_pscreen:
 +   dri2DestroyScreen(vl_dri_scrn->dri_screen);
 +no_dri2screen:
 +   FREE(vl_dri_scrn);
 +no_struct:
 +   return NULL;
 +}
 +
 +void vl_screen_destroy(struct vl_screen *vscreen)
 +{
 +   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen;
 +
 +   assert(vscreen);
 +
 +   util_hash_table_foreach(vl_dri_scrn->drawable_table, drawable_destroy, vl_dri_scrn);
 +   util_hash_table_destroy(vl_dri_scrn->drawable_table);
 +   vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen);
 +   dri2DestroyScreen(vl_dri_scrn->dri_screen);
 +   FREE(vl_dri_scrn);
 +}
 +
 +struct vl_context*
 +vl_video_create(struct vl_screen *vscreen,
 +                enum pipe_video_profile profile,
 +                enum pipe_video_chroma_format chroma_format,
 +                unsigned width, unsigned height)
 +{
 +   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen;
 +   struct vl_dri_context *vl_dri_ctx;
 +
 +   vl_dri_ctx = CALLOC_STRUCT(vl_dri_context);
 +   if (!vl_dri_ctx)
 +      goto no_struct;
 +
 +   if (!vscreen->pscreen->video_context_create) {
 +      debug_printf("[G3DVL] No video support found on %s/%s.\n",
 +                   vscreen->pscreen->get_vendor(vscreen->pscreen),
 +                   vscreen->pscreen->get_name(vscreen->pscreen));
 +      goto no_vpipe;
 +   }
 +
 +   vl_dri_ctx->base.vpipe = vscreen->pscreen->video_context_create(vscreen->pscreen,
 +                                                                   profile, chroma_format,
 +                                                                   width, height,
 +                                                                   vl_dri_ctx);
 +
 +   if (!vl_dri_ctx->base.vpipe)
 +      goto no_vpipe;
 +
 +   vl_dri_ctx->base.vpipe->priv = vl_dri_ctx;
 +   vl_dri_ctx->base.vscreen = vscreen;
 +   vl_dri_ctx->fd = vl_dri_scrn->dri_screen->fd;
 +
 +   return &vl_dri_ctx->base;
 +
 +no_vpipe:
 +   FREE(vl_dri_ctx);
 +no_struct:
 +   return NULL;
 +}
 +
 +void vl_video_destroy(struct vl_context *vctx)
 +{
 +   struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)vctx;
 +
 +   assert(vctx);
 +
 +   vl_dri_ctx->base.vpipe->destroy(vl_dri_ctx->base.vpipe);
 +   FREE(vl_dri_ctx);
 +}
index 381478637a8fa06f25be68641fcad0ccb5152c2f,0000000000000000000000000000000000000000..58f548849f6dd6e38b93befd6482b88c832cd520
mode 100644,000000..100644
--- /dev/null
@@@ -1,69 -1,0 +1,69 @@@
- vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable);
 +/**************************************************************************
 + *
 + * Copyright 2009 Younes Manton.
 + * 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 TUNGSTEN GRAPHICS 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.
 + *
 + **************************************************************************/
 +
 +#ifndef vl_winsys_h
 +#define vl_winsys_h
 +
 +#include <X11/Xlib.h>
 +#include <pipe/p_defines.h>
 +#include <pipe/p_format.h>
 +
 +struct pipe_screen;
 +struct pipe_video_context;
 +struct pipe_surface;
 +
 +struct vl_screen
 +{
 +   struct pipe_screen *pscreen;
 +};
 +
 +struct vl_context
 +{
 +   struct vl_screen *vscreen;
 +   struct pipe_video_context *vpipe;
 +};
 +
 +struct vl_screen*
 +vl_screen_create(Display *display, int screen);
 +
 +void vl_screen_destroy(struct vl_screen *vscreen);
 +
 +struct vl_context*
 +vl_video_create(struct vl_screen *vscreen,
 +                enum pipe_video_profile profile,
 +                enum pipe_video_chroma_format chroma_format,
 +                unsigned width, unsigned height);
 +
 +void vl_video_destroy(struct vl_context *vctx);
 +
 +struct pipe_surface*
++vl_drawable_surface_get(struct vl_context *vctx, Drawable drawable);
 +
 +void*
 +vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *drawable_surface);
 +
 +#endif