[g3dvl] give each color component their own vertex buffer
authorChristian König <deathsimple@vodafone.de>
Sun, 17 Apr 2011 21:21:32 +0000 (23:21 +0200)
committerChristian König <deathsimple@vodafone.de>
Sun, 17 Apr 2011 21:21:32 +0000 (23:21 +0200)
src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
src/gallium/auxiliary/vl/vl_mpeg12_decoder.h
src/gallium/auxiliary/vl/vl_vertex_buffers.c
src/gallium/auxiliary/vl/vl_vertex_buffers.h

index 10c9c64..7e72fba 100644 (file)
@@ -268,7 +268,6 @@ static void
 vl_mpeg12_destroy(struct pipe_video_decoder *decoder)
 {
    struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
-   unsigned i;
 
    assert(decoder);
 
@@ -286,9 +285,7 @@ vl_mpeg12_destroy(struct pipe_video_decoder *decoder)
       vl_idct_cleanup(&dec->idct_c);
    }
 
-   for (i = 0; i < VL_MAX_PLANES; ++i)
-      dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_eb[i]);
-
+   dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_ycbcr);
    dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_mv);
 
    pipe_resource_reference(&dec->quads.buffer, NULL);
@@ -457,7 +454,6 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
 
    struct pipe_vertex_buffer vb[3];
 
-   unsigned num_instances;
    unsigned i, j;
 
    assert(buf);
@@ -470,8 +466,6 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
 
    surfaces = dst->get_surfaces(dst);
 
-   num_instances = vl_vb_restart(&buf->vertex_stream);
-
    vb[0] = dec->quads;
    vb[1] = dec->pos;
 
@@ -489,11 +483,13 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
       }
    }
 
-   vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream);
-   dec->pipe->set_vertex_buffers(dec->pipe, 2, vb);
-
+   dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_ycbcr);
    for (i = 0; i < VL_MAX_PLANES; ++i) {
-      dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_eb[i]);
+      unsigned num_instances = vl_vb_restart(&buf->vertex_stream, i);
+
+      vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i);
+      dec->pipe->set_vertex_buffers(dec->pipe, 2, vb);
+
       if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
          vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], num_instances);
 
@@ -507,10 +503,12 @@ static void
 vl_mpeg12_decoder_clear_buffer(struct pipe_video_decode_buffer *buffer)
 {
    struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
+   unsigned i;
 
    assert(buf);
 
-   vl_vb_restart(&buf->vertex_stream);
+   for (i = 0; i < VL_MAX_PLANES; ++i)
+      vl_vb_restart(&buf->vertex_stream, i);
 }
 
 static bool
@@ -673,7 +671,6 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
 {
    struct vl_mpeg12_decoder *dec;
    float mc_scale;
-   unsigned i;
 
    assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
 
@@ -706,9 +703,7 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
       dec->base.height / MACROBLOCK_HEIGHT
    );
 
-   for (i = 0; i < VL_MAX_PLANES; ++i)
-      dec->ves_eb[i] = vl_vb_get_ves_eb(dec->pipe, i);
-
+   dec->ves_ycbcr = vl_vb_get_ves_ycbcr(dec->pipe);
    dec->ves_mv = vl_vb_get_ves_mv(dec->pipe);
 
    /* TODO: Implement 422, 444 */
index 6a6fabd..c961e43 100644 (file)
@@ -54,7 +54,7 @@ struct vl_mpeg12_decoder
    struct pipe_vertex_buffer quads;
    struct pipe_vertex_buffer pos;
 
-   void *ves_eb[VL_MAX_PLANES];
+   void *ves_ycbcr;
    void *ves_mv;
 
    struct vl_idct idct_y, idct_c;
index 7614255..89815c4 100644 (file)
 #include "vl_vertex_buffers.h"
 #include "vl_types.h"
 
-struct vl_vertex_stream
+struct vl_ycbcr_vertex_stream
 {
    struct vertex2s pos;
    uint8_t mb_type_intra;
    uint8_t dct_type_field;
    uint8_t dummy[2];
-   uint8_t eb[3][2][2];
+   uint8_t eb[2][2];
 };
 
 struct vl_mv_vertex_stream
@@ -169,10 +169,7 @@ vl_vb_element_helper(struct pipe_vertex_element* elements, unsigned num_elements
    assert(elements && num_elements);
 
    for ( i = 0; i < num_elements; ++i ) {
-      if (elements[i].src_offset)
-         offset = elements[i].src_offset;
-      else
-         elements[i].src_offset = offset;
+      elements[i].src_offset = offset;
       elements[i].instance_divisor = 1;
       elements[i].vertex_buffer_index = vertex_buffer_index;
       offset += util_format_get_blocksize(elements[i].src_format);
@@ -180,7 +177,7 @@ vl_vb_element_helper(struct pipe_vertex_element* elements, unsigned num_elements
 }
 
 void *
-vl_vb_get_ves_eb(struct pipe_context *pipe, int component)
+vl_vb_get_ves_ycbcr(struct pipe_context *pipe)
 {
    struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS];
 
@@ -196,7 +193,6 @@ vl_vb_get_ves_eb(struct pipe_context *pipe, int component)
    vertex_elems[VS_I_FLAGS].src_format = PIPE_FORMAT_R8G8B8A8_USCALED;
 
    /* empty block element of selected component */
-   vertex_elems[VS_I_EB].src_offset = offsetof(struct vl_vertex_stream, eb[component]);
    vertex_elems[VS_I_EB].src_format = PIPE_FORMAT_R8G8B8A8_USCALED;
 
    vl_vb_element_helper(&vertex_elems[VS_I_VPOS], NUM_VS_INPUTS - 1, 1);
@@ -233,21 +229,25 @@ vl_vb_get_ves_mv(struct pipe_context *pipe)
 void
 vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe, unsigned width, unsigned height)
 {
-   unsigned i;
+   unsigned i, size;
 
    assert(buffer);
 
    buffer->width = width;
    buffer->height = height;
-   buffer->num_instances = 0;
 
-   buffer->resource = pipe_buffer_create
-   (
-      pipe->screen,
-      PIPE_BIND_VERTEX_BUFFER,
-      PIPE_USAGE_STREAM,
-      sizeof(struct vl_vertex_stream) * width * height
-   );
+   size = width * height;
+
+   for (i = 0; i < VL_MAX_PLANES; ++i) {
+      buffer->ycbcr[i].num_instances = 0;
+      buffer->ycbcr[i].resource = pipe_buffer_create
+      (
+         pipe->screen,
+         PIPE_BIND_VERTEX_BUFFER,
+         PIPE_USAGE_STREAM,
+         sizeof(struct vl_ycbcr_vertex_stream) * size
+      );
+   }
 
    for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
       buffer->mv[i].resource = pipe_buffer_create
@@ -255,7 +255,7 @@ vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe, unsigned
          pipe->screen,
          PIPE_BIND_VERTEX_BUFFER,
          PIPE_USAGE_STREAM,
-         sizeof(struct vl_mv_vertex_stream) * width * height
+         sizeof(struct vl_mv_vertex_stream) * size
       );
    }
 
@@ -263,15 +263,15 @@ vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe, unsigned
 }
 
 struct pipe_vertex_buffer
-vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer)
+vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer, int component)
 {
    struct pipe_vertex_buffer buf;
 
    assert(buffer);
 
-   buf.stride = sizeof(struct vl_vertex_stream);
+   buf.stride = sizeof(struct vl_ycbcr_vertex_stream);
    buf.buffer_offset = 0;
-   buf.buffer = buffer->resource;
+   buf.buffer = buffer->ycbcr[component].resource;
 
    return buf;
 }
@@ -297,13 +297,15 @@ vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe)
 
    assert(buffer && pipe);
 
-   buffer->buffer = pipe_buffer_map
-   (
-      pipe,
-      buffer->resource,
-      PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
-      &buffer->transfer
-   );
+   for (i = 0; i < VL_MAX_PLANES; ++i) {
+      buffer->ycbcr[i].vertex_stream = pipe_buffer_map
+      (
+         pipe,
+         buffer->ycbcr[i].resource,
+         PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+         &buffer->ycbcr[i].transfer
+      );
+   }
 
    for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
       buffer->mv[i].vertex_stream = pipe_buffer_map
@@ -339,31 +341,45 @@ get_motion_vectors(enum pipe_mpeg12_motion_type mo_type, struct pipe_motionvecto
    dst[1].w = src->bottom.wheight;
 }
 
+static bool
+get_ycbcr_vectors(struct vl_ycbcr_vertex_stream *stream,
+                  struct pipe_mpeg12_macroblock *mb, const unsigned (*empty_block_mask)[2][2])
+{
+   bool completely_empty = true;
+   unsigned i, j;
+
+   stream->pos.x = mb->mbx;
+   stream->pos.y = mb->mby;
+   stream->dct_type_field = mb->dct_type == PIPE_MPEG12_DCT_TYPE_FIELD;
+   stream->mb_type_intra = mb->dct_intra;
+
+   for ( i = 0; i < 2; ++i)
+      for ( j = 0; j < 2; ++j) {
+         bool empty = !(mb->cbp & (*empty_block_mask)[i][j]);
+         stream->eb[i][j] = empty;
+         completely_empty &= empty;
+      }
+
+   return !completely_empty;
+}
+
 void
 vl_vb_add_block(struct vl_vertex_buffer *buffer, struct pipe_mpeg12_macroblock *mb,
                 const unsigned (*empty_block_mask)[3][2][2])
 {
-   unsigned i, j, k;
-   unsigned mv_pos;
+   unsigned i, mv_pos;
 
    assert(buffer);
    assert(mb);
-   assert(buffer->num_instances < buffer->width * buffer->height);
 
    if(mb->cbp) {
-      struct vl_vertex_stream *stream;
-      stream = buffer->buffer + buffer->num_instances++;
-
-      stream->pos.x = mb->mbx;
-      stream->pos.y = mb->mby;
-
-      for ( i = 0; i < 3; ++i)
-         for ( j = 0; j < 2; ++j)
-            for ( k = 0; k < 2; ++k)
-               stream->eb[i][j][k] = !(mb->cbp & (*empty_block_mask)[i][j][k]);
-
-      stream->dct_type_field = mb->dct_type == PIPE_MPEG12_DCT_TYPE_FIELD;
-      stream->mb_type_intra = mb->dct_intra;
+      for (i = 0; i < VL_MAX_PLANES; ++i) {
+         assert(buffer->ycbcr[i].num_instances < buffer->width * buffer->height);
+         if (get_ycbcr_vectors(buffer->ycbcr[i].vertex_stream, mb, &(*empty_block_mask)[i])) {
+            buffer->ycbcr[i].vertex_stream++;
+            buffer->ycbcr[i].num_instances++;
+         }
+      }
    }
 
    mv_pos = mb->mbx + mb->mby * buffer->width;
@@ -378,21 +394,24 @@ vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe)
 
    assert(buffer && pipe);
 
-   pipe_buffer_unmap(pipe, buffer->transfer);
+   for (i = 0; i < VL_MAX_PLANES; ++i) {
+      pipe_buffer_unmap(pipe, buffer->ycbcr[i].transfer);
+   }
+
    for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
       pipe_buffer_unmap(pipe, buffer->mv[i].transfer);
    }
 }
 
 unsigned
-vl_vb_restart(struct vl_vertex_buffer *buffer)
+vl_vb_restart(struct vl_vertex_buffer *buffer, int component)
 {
    unsigned num_instances;
 
    assert(buffer);
 
-   num_instances = buffer->num_instances;
-   buffer->num_instances = 0;
+   num_instances = buffer->ycbcr[component].num_instances;
+   buffer->ycbcr[component].num_instances = 0;
    return num_instances;
 }
 
@@ -403,7 +422,9 @@ vl_vb_cleanup(struct vl_vertex_buffer *buffer)
 
    assert(buffer);
 
-   pipe_resource_reference(&buffer->resource, NULL);
+   for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
+      pipe_resource_reference(&buffer->ycbcr[i].resource, NULL);
+   }
 
    for (i = 0; i < VL_MAX_REF_FRAMES; ++i) {
       pipe_resource_reference(&buffer->mv[i].resource, NULL);
index ce169cc..3d9c614 100644 (file)
@@ -56,11 +56,13 @@ enum VS_INPUT
 struct vl_vertex_buffer
 {
    unsigned width, height;
-   unsigned num_instances;
 
-   struct pipe_resource *resource;
-   struct pipe_transfer *transfer;
-   struct vl_vertex_stream *buffer;
+   struct {
+      unsigned                      num_instances;
+      struct pipe_resource          *resource;
+      struct pipe_transfer          *transfer;
+      struct vl_ycbcr_vertex_stream *vertex_stream;
+   } ycbcr[VL_MAX_PLANES];
 
    struct {
       struct pipe_resource       *resource;
@@ -74,7 +76,7 @@ struct pipe_vertex_buffer vl_vb_upload_quads(struct pipe_context *pipe,
 
 struct pipe_vertex_buffer vl_vb_upload_pos(struct pipe_context *pipe, unsigned width, unsigned height);
 
-void *vl_vb_get_ves_eb(struct pipe_context *pipe, int component);
+void *vl_vb_get_ves_ycbcr(struct pipe_context *pipe);
 
 void *vl_vb_get_ves_mv(struct pipe_context *pipe);
 
@@ -82,7 +84,7 @@ void vl_vb_init(struct vl_vertex_buffer *buffer,
                 struct pipe_context *pipe,
                 unsigned width, unsigned height);
 
-struct pipe_vertex_buffer vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer);
+struct pipe_vertex_buffer vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer, int component);
 
 struct pipe_vertex_buffer vl_vb_get_mv(struct vl_vertex_buffer *buffer, int motionvector);
 
@@ -93,7 +95,7 @@ void vl_vb_add_block(struct vl_vertex_buffer *buffer, struct pipe_mpeg12_macrobl
 
 void vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe);
 
-unsigned vl_vb_restart(struct vl_vertex_buffer *buffer);
+unsigned vl_vb_restart(struct vl_vertex_buffer *buffer, int component);
 
 void vl_vb_cleanup(struct vl_vertex_buffer *buffer);