[g3dvl] fully support different formats for source and intermediate textures
authorChristian König <deathsimple@vodafone.de>
Mon, 11 Apr 2011 21:55:36 +0000 (23:55 +0200)
committerChristian König <deathsimple@vodafone.de>
Mon, 11 Apr 2011 21:55:36 +0000 (23:55 +0200)
src/gallium/auxiliary/vl/vl_idct.c
src/gallium/auxiliary/vl/vl_idct.h
src/gallium/auxiliary/vl/vl_mpeg12_decoder.c

index f8e0f02c4f42e5c6a63cb9de7a8c8685d53fd363..a20263bc182b19977dce5af0542f1b5a6074b6aa 100644 (file)
@@ -585,7 +585,8 @@ bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe,
                   unsigned buffer_width, unsigned buffer_height,
                   unsigned blocks_x, unsigned blocks_y,
                   unsigned nr_of_render_targets,
-                  struct pipe_sampler_view *matrix)
+                  struct pipe_sampler_view *matrix,
+                  struct pipe_sampler_view *transpose)
 {
    assert(idct && pipe && matrix);
 
@@ -595,7 +596,9 @@ bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe,
    idct->blocks_x = blocks_x;
    idct->blocks_y = blocks_y;
    idct->nr_of_render_targets = nr_of_render_targets;
+
    pipe_sampler_view_reference(&idct->matrix, matrix);
+   pipe_sampler_view_reference(&idct->transpose, transpose);
 
    if(!init_shaders(idct))
       return false;
@@ -632,7 +635,7 @@ vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer,
 
    pipe_sampler_view_reference(&buffer->sampler_views.individual.matrix, idct->matrix);
    pipe_sampler_view_reference(&buffer->sampler_views.individual.source, source);
-   pipe_sampler_view_reference(&buffer->sampler_views.individual.transpose, idct->matrix);
+   pipe_sampler_view_reference(&buffer->sampler_views.individual.transpose, idct->transpose);
    pipe_sampler_view_reference(&buffer->sampler_views.individual.intermediate, intermediate);
 
    if (!init_intermediate(idct, buffer))
index e695e32efe3907e0d16a53ca619e55004a7596af..0875f17476c55abf20762374519d5a9dea79ad1f 100644 (file)
@@ -50,6 +50,7 @@ struct vl_idct
    void *matrix_fs, *transpose_fs;
 
    struct pipe_sampler_view *matrix;
+   struct pipe_sampler_view *transpose;
 };
 
 /* a set of buffers to work with */
@@ -77,7 +78,8 @@ bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe,
                   unsigned buffer_width, unsigned buffer_height,
                   unsigned blocks_x, unsigned blocks_y,
                   unsigned nr_of_render_targets,
-                  struct pipe_sampler_view *matrix);
+                  struct pipe_sampler_view *matrix,
+                  struct pipe_sampler_view *transpose);
 
 /* destroy an idct instance */
 void vl_idct_cleanup(struct vl_idct *idct);
index d9cf13baec7aece1839caa3cb0926c548b68618f..40a1b74f654ac73e52dea46408aa86a6bd73f447 100644 (file)
 #include "vl_mpeg12_decoder.h"
 #include "vl_defines.h"
 
-#define SCALE_FACTOR_16_TO_9 (32768.0f / 256.0f)
+#define SCALE_FACTOR_SNORM (32768.0f / 256.0f)
+#define SCALE_FACTOR_SSCALED (1.0f / 256.0f)
 
 static const unsigned const_empty_block_mask_420[3][2][2] = {
-        { { 0x20, 0x10 },  { 0x08, 0x04 } },
-        { { 0x02, 0x02 },  { 0x02, 0x02 } },
-        { { 0x01, 0x01 },  { 0x01, 0x01 } }
+   { { 0x20, 0x10 },  { 0x08, 0x04 } },
+   { { 0x02, 0x02 },  { 0x02, 0x02 } },
+   { { 0x01, 0x01 },  { 0x01, 0x01 } }
 };
 
 static const enum pipe_format const_idct_source_formats[] = {
-   PIPE_FORMAT_R16G16B16A16_SNORM
-   //PIPE_FORMAT_R16G16B16A16_SSCALED
+   PIPE_FORMAT_R16G16B16A16_SNORM,
+   PIPE_FORMAT_R16G16B16A16_SSCALED
 };
 
 static const unsigned num_idct_source_formats =
@@ -53,17 +54,17 @@ static const unsigned num_idct_source_formats =
 
 static const enum pipe_format const_idct_intermediate_formats[] = {
    PIPE_FORMAT_R16G16B16A16_FLOAT,
-   PIPE_FORMAT_R16G16B16A16_SNORM
-   //PIPE_FORMAT_R32G32B32A32_FLOAT,
-   //PIPE_FORMAT_R16G16B16A16_SSCALED
+   PIPE_FORMAT_R16G16B16A16_SNORM,
+   PIPE_FORMAT_R16G16B16A16_SSCALED,
+   PIPE_FORMAT_R32G32B32A32_FLOAT
 };
 
 static const unsigned num_idct_intermediate_formats =
    sizeof(const_idct_intermediate_formats) / sizeof(enum pipe_format);
 
 static const enum pipe_format const_mc_source_formats[] = {
-   PIPE_FORMAT_R16_SNORM
-   //PIPE_FORMAT_R16_SSCALED
+   PIPE_FORMAT_R16_SNORM,
+   PIPE_FORMAT_R16_SSCALED
 };
 
 static const unsigned num_mc_source_formats =
@@ -571,7 +572,8 @@ static bool
 init_idct(struct vl_mpeg12_decoder *dec, unsigned buffer_width, unsigned buffer_height)
 {
    unsigned chroma_width, chroma_height, chroma_blocks_x, chroma_blocks_y;
-   struct pipe_sampler_view *idct_matrix;
+   struct pipe_sampler_view *matrix, *transpose;
+   float matrix_scale, transpose_scale;
 
    dec->nr_of_idct_render_targets = dec->pipe->screen->get_param(dec->pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS);
 
@@ -590,12 +592,41 @@ init_idct(struct vl_mpeg12_decoder *dec, unsigned buffer_width, unsigned buffer_
    if (dec->idct_intermediate_format == PIPE_FORMAT_NONE)
       return false;
 
-   if (!(idct_matrix = vl_idct_upload_matrix(dec->pipe, sqrt(SCALE_FACTOR_16_TO_9))))
-      goto error_idct_matrix;
+   switch (dec->idct_source_format) {
+   case PIPE_FORMAT_R16G16B16A16_SSCALED:
+      matrix_scale = SCALE_FACTOR_SSCALED;
+      break;
+
+   case PIPE_FORMAT_R16G16B16A16_SNORM:
+      matrix_scale = SCALE_FACTOR_SNORM;
+      break;
+
+   default:
+      assert(0);
+      return false;
+   }
+
+   if (dec->idct_intermediate_format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
+       dec->idct_intermediate_format == PIPE_FORMAT_R32G32B32A32_FLOAT)
+      transpose_scale = 1.0f;
+   else
+      transpose_scale = matrix_scale = sqrt(matrix_scale);
+
+   if (dec->mc_source_format == PIPE_FORMAT_R16_SSCALED)
+      transpose_scale /= SCALE_FACTOR_SSCALED;
+
+   if (!(matrix = vl_idct_upload_matrix(dec->pipe, matrix_scale)))
+      goto error_matrix;
+
+   if (matrix_scale != transpose_scale) {
+      if (!(transpose = vl_idct_upload_matrix(dec->pipe, transpose_scale)))
+         goto error_transpose;
+   } else
+      pipe_sampler_view_reference(&transpose, matrix);
 
    if (!vl_idct_init(&dec->idct_y, dec->pipe, buffer_width, buffer_height,
-                     2, 2, dec->nr_of_idct_render_targets, idct_matrix))
-      goto error_idct_y;
+                     2, 2, dec->nr_of_idct_render_targets, matrix, transpose))
+      goto error_y;
 
    if (dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
       chroma_width = buffer_width / 2;
@@ -616,19 +647,23 @@ init_idct(struct vl_mpeg12_decoder *dec, unsigned buffer_width, unsigned buffer_
 
    if(!vl_idct_init(&dec->idct_c, dec->pipe, chroma_width, chroma_height,
                     chroma_blocks_x, chroma_blocks_y,
-                    dec->nr_of_idct_render_targets, idct_matrix))
-      goto error_idct_c;
+                    dec->nr_of_idct_render_targets, matrix, transpose))
+      goto error_c;
 
-   pipe_sampler_view_reference(&idct_matrix, NULL);
+   pipe_sampler_view_reference(&matrix, NULL);
+   pipe_sampler_view_reference(&transpose, NULL);
    return true;
 
-error_idct_c:
+error_c:
    vl_idct_cleanup(&dec->idct_y);
 
-error_idct_y:
-   pipe_sampler_view_reference(&idct_matrix, NULL);
+error_y:
+   pipe_sampler_view_reference(&transpose, NULL);
+
+error_transpose:
+   pipe_sampler_view_reference(&matrix, NULL);
 
-error_idct_matrix:
+error_matrix:
    return false;
 }
 
@@ -641,6 +676,7 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
                          unsigned width, unsigned height)
 {
    struct vl_mpeg12_decoder *dec;
+   float mc_scale;
    unsigned i;
 
    assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
@@ -675,19 +711,37 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
    assert(dec->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
    dec->empty_block_mask = &const_empty_block_mask_420;
 
-   if (!vl_mpeg12_mc_renderer_init(&dec->mc, dec->pipe, dec->base.width, dec->base.height,
-                                   entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT ? 1.0f : SCALE_FACTOR_16_TO_9))
-      goto error_mc;
-
-   if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
-      if (!init_idct(dec, dec->base.width, dec->base.height))
-         goto error_idct;
-
    dec->mc_source_format = find_first_supported_format(dec, const_mc_source_formats,
                                                        num_mc_source_formats, PIPE_TEXTURE_3D);
 
    if (dec->mc_source_format == PIPE_FORMAT_NONE)
-      return false;
+      return NULL;
+
+   if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
+      if (!init_idct(dec, dec->base.width, dec->base.height))
+         goto error_idct;
+      if (dec->mc_source_format == PIPE_FORMAT_R16_SSCALED)
+         mc_scale = SCALE_FACTOR_SSCALED;
+      else
+         mc_scale = 1.0f;
+   } else {
+      switch (dec->mc_source_format) {
+      case PIPE_FORMAT_R16_SNORM:
+         mc_scale = SCALE_FACTOR_SNORM;
+         break;
+
+      case PIPE_FORMAT_R16_SSCALED:
+         mc_scale = SCALE_FACTOR_SSCALED;
+         break;
+
+      default:
+         assert(0);
+         return NULL;
+      }
+   }
+
+   if (!vl_mpeg12_mc_renderer_init(&dec->mc, dec->pipe, dec->base.width, dec->base.height, mc_scale))
+      goto error_mc;
 
    if (!init_pipe_state(dec))
       goto error_pipe_state;