vl: initial implementation of vlVaQueryImageFormats(), vlVaCreateImage(), vlVaQuerySu...
[mesa.git] / src / gallium / auxiliary / vl / vl_mpeg12_mc_renderer.c
index a4a9320d6675e8ef8f925d8b827bf85e6be3c0f2..75e09deabc44d7c064bcefcc68d0a9a72c2ce46c 100644 (file)
  **************************************************************************/
 
 #include "vl_mpeg12_mc_renderer.h"
+#include "util/u_draw.h"
 #include <assert.h>
 #include <pipe/p_context.h>
 #include <util/u_inlines.h>
 #include <util/u_format.h>
 #include <util/u_math.h>
 #include <util/u_memory.h>
+#include <util/u_keymap.h>
 #include <util/u_sampler.h>
+#include <util/u_draw.h>
 #include <tgsi/tgsi_ureg.h>
 
 #define DEFAULT_BUF_ALIGNMENT 1
@@ -276,6 +279,7 @@ create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
    for (i = 0; i < 4; ++i)
       vtex[i] = ureg_DECL_vs_input(shader, i + 1);
    /* Skip input 5 */
+   ureg_DECL_vs_input(shader, 5);
    vtex[4] = ureg_DECL_vs_input(shader, 6);
    o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0);
    for (i = 0; i < 5; ++i)
@@ -384,7 +388,7 @@ xfer_buffers_map(struct vl_mpeg12_mc_renderer *r)
          0, 0, 0,
          r->textures.all[i]->width0,
          r->textures.all[i]->height0,
-         0
+         1
       };
 
       r->tex_transfer[i] = r->pipe->get_transfer
@@ -456,6 +460,7 @@ init_pipe_state(struct vl_mpeg12_mc_renderer *r)
    filters[4] = PIPE_TEX_FILTER_LINEAR;
 
    for (i = 0; i < 5; ++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;
@@ -602,6 +607,8 @@ init_buffers(struct vl_mpeg12_mc_renderer *r)
       );
    }
 
+   memset(&vertex_elems, 0, sizeof(vertex_elems));
+
    /* Position element */
    vertex_elems[0].src_offset = 0;
    vertex_elems[0].instance_divisor = 0;
@@ -674,7 +681,7 @@ cleanup_buffers(struct vl_mpeg12_mc_renderer *r)
    pipe_resource_reference(&r->vs_const_buf, NULL);
 
    for (i = 0; i < 3; ++i) {
-      r->pipe->sampler_view_destroy(r->pipe, r->sampler_views.all[i]);
+      pipe_sampler_view_reference(&r->sampler_views.all[i], NULL);
       r->pipe->delete_vertex_elements_state(r->pipe, r->vertex_elems_state.all[i]);
       pipe_resource_reference(&r->vertex_bufs.all[i].buffer, NULL);
       pipe_resource_reference(&r->textures.all[i], NULL);
@@ -885,7 +892,7 @@ gen_macroblock_verts(struct vl_mpeg12_mc_renderer *r,
             }
          }
 
-         if (mb->mb_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
+         if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
             for (i = 0; i < 24 * 2; i += 2) {
                vb[i].x = mo_vec[0].x;
                vb[i].y = mo_vec[0].y;
@@ -1004,6 +1011,33 @@ gen_macroblock_stream(struct vl_mpeg12_mc_renderer *r,
       pipe_buffer_unmap(r->pipe, r->vertex_bufs.individual.ref[i].buffer, buf_transfer[i + 1]);
 }
 
+static struct pipe_sampler_view
+*find_or_create_sampler_view(struct vl_mpeg12_mc_renderer *r, struct pipe_surface *surface)
+{
+   struct pipe_sampler_view *sampler_view;
+   assert(r);
+   assert(surface);
+
+   sampler_view = (struct pipe_sampler_view*)util_keymap_lookup(r->texview_map, &surface);
+   if (!sampler_view) {
+      struct pipe_sampler_view templat;
+      boolean added_to_map;
+
+      u_sampler_view_default_template(&templat, surface->texture,
+                                      surface->texture->format);
+      sampler_view = r->pipe->create_sampler_view(r->pipe, surface->texture,
+                                                  &templat);
+      if (!sampler_view)
+         return NULL;
+
+      added_to_map = util_keymap_insert(r->texview_map, &surface,
+                                        sampler_view, r->pipe);
+      assert(added_to_map);
+   }
+
+   return sampler_view;
+}
+
 static void
 flush(struct vl_mpeg12_mc_renderer *r)
 {
@@ -1011,6 +1045,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
    unsigned vb_start = 0;
    struct vertex_shader_consts *vs_consts;
    struct pipe_transfer *buf_transfer;
+   
    unsigned i;
 
    assert(r);
@@ -1037,6 +1072,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
 
    r->pipe->set_constant_buffer(r->pipe, PIPE_SHADER_VERTEX, 0,
                                 r->vs_const_buf);
+                                                               
 
    if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) {
       r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all);
@@ -1046,22 +1082,24 @@ flush(struct vl_mpeg12_mc_renderer *r)
       r->pipe->bind_vs_state(r->pipe, r->i_vs);
       r->pipe->bind_fs_state(r->pipe, r->i_fs);
 
-      r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
-                           num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24);
+      util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24);
+
       vb_start += num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24;
    }
 
-   if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0*/) {
+   if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0) {
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
       r->textures.individual.ref[0] = r->past->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
       r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[0]);
       r->pipe->bind_fs_state(r->pipe, r->p_fs[0]);
 
-      r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
-                           num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24);
+      util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24);
+
+
       vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24;
    }
 
@@ -1069,27 +1107,30 @@ flush(struct vl_mpeg12_mc_renderer *r)
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
       r->textures.individual.ref[0] = r->past->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
       r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[1]);
       r->pipe->bind_fs_state(r->pipe, r->p_fs[1]);
 
-      r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
-                           num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24);
+      util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24);
+
+
       vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24;
    }
 
-   if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0*/) {
+   if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0) {
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
       r->textures.individual.ref[0] = r->future->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->future);
       r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[0]);
       r->pipe->bind_fs_state(r->pipe, r->p_fs[0]);
 
-      r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
-                           num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24);
+      util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24);
+
       vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24;
    }
 
@@ -1097,28 +1138,32 @@ flush(struct vl_mpeg12_mc_renderer *r)
       r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
       r->textures.individual.ref[0] = r->future->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->future);
       r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->p_vs[1]);
       r->pipe->bind_fs_state(r->pipe, r->p_fs[1]);
 
-      r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
-                           num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24);
+      util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24);
+
       vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24;
    }
 
-   if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0*/) {
+   if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0) {
       r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.b);
       r->textures.individual.ref[0] = r->past->texture;
       r->textures.individual.ref[1] = r->future->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+      r->sampler_views.individual.ref[1] = find_or_create_sampler_view(r, r->future);
       r->pipe->set_fragment_sampler_views(r->pipe, 5, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->b_vs[0]);
       r->pipe->bind_fs_state(r->pipe, r->b_fs[0]);
 
-      r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
-                           num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24);
+
+      util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24);
+
       vb_start += num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24;
    }
 
@@ -1127,13 +1172,15 @@ flush(struct vl_mpeg12_mc_renderer *r)
       r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.b);
       r->textures.individual.ref[0] = r->past->texture;
       r->textures.individual.ref[1] = r->future->texture;
+      r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+      r->sampler_views.individual.ref[1] = find_or_create_sampler_view(r, r->future);
       r->pipe->set_fragment_sampler_views(r->pipe, 5, r->sampler_views.all);
       r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all);
       r->pipe->bind_vs_state(r->pipe, r->b_vs[1]);
       r->pipe->bind_fs_state(r->pipe, r->b_fs[1]);
 
-      r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
-                           num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] * 24);
+      util_draw_arrays(r->pipe,PIPE_PRIM_TRIANGLES,vb_start,num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] * 24);
+
       vb_start += num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] * 24;
    }
 
@@ -1270,6 +1317,21 @@ grab_macroblock(struct vl_mpeg12_mc_renderer *r,
    ++r->num_macroblocks;
 }
 
+static void
+texview_map_delete(const struct keymap *map,
+                   const void *key, void *data,
+                   void *user)
+{
+   struct pipe_sampler_view *sv = (struct pipe_sampler_view*)data;
+
+   assert(map);
+   assert(key);
+   assert(data);
+   assert(user);
+
+   pipe_sampler_view_reference(&sv, NULL);
+}
+
 bool
 vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
                            struct pipe_context *pipe,
@@ -1302,13 +1364,22 @@ vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
    renderer->eb_handling = eb_handling;
    renderer->pot_buffers = pot_buffers;
 
-   if (!init_pipe_state(renderer))
+   renderer->texview_map = util_new_keymap(sizeof(struct pipe_surface*), -1,
+                                           texview_map_delete);
+   if (!renderer->texview_map)
       return false;
+
+   if (!init_pipe_state(renderer)) {
+      util_delete_keymap(renderer->texview_map, renderer->pipe);
+      return false;
+   }
    if (!init_shaders(renderer)) {
+      util_delete_keymap(renderer->texview_map, renderer->pipe);
       cleanup_pipe_state(renderer);
       return false;
    }
    if (!init_buffers(renderer)) {
+      util_delete_keymap(renderer->texview_map, renderer->pipe);
       cleanup_shaders(renderer);
       cleanup_pipe_state(renderer);
       return false;
@@ -1333,6 +1404,7 @@ vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer)
 
    xfer_buffers_unmap(renderer);
 
+   util_delete_keymap(renderer->texview_map, renderer->pipe);
    cleanup_pipe_state(renderer);
    cleanup_shaders(renderer);
    cleanup_buffers(renderer);