"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/r600/r600_uvd.c" (16 Sep 2020, 6128 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "r600_uvd.c" see the Fossies "Dox" file reference documentation.

    1 /**************************************************************************
    2  *
    3  * Copyright 2011 Advanced Micro Devices, Inc.
    4  * All Rights Reserved.
    5  *
    6  * Permission is hereby granted, free of charge, to any person obtaining a
    7  * copy of this software and associated documentation files (the
    8  * "Software"), to deal in the Software without restriction, including
    9  * without limitation the rights to use, copy, modify, merge, publish,
   10  * distribute, sub license, and/or sell copies of the Software, and to
   11  * permit persons to whom the Software is furnished to do so, subject to
   12  * the following conditions:
   13  *
   14  * The above copyright notice and this permission notice (including the
   15  * next paragraph) shall be included in all copies or substantial portions
   16  * of the Software.
   17  *
   18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
   21  * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
   22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   25  *
   26  **************************************************************************/
   27 
   28 /*
   29  * Authors:
   30  *      Christian König <christian.koenig@amd.com>
   31  *
   32  */
   33 
   34 #include <sys/types.h>
   35 #include <assert.h>
   36 #include <errno.h>
   37 #include <unistd.h>
   38 
   39 #include "pipe/p_video_codec.h"
   40 
   41 #include "util/u_memory.h"
   42 #include "util/u_video.h"
   43 
   44 #include "vl/vl_defines.h"
   45 #include "vl/vl_mpeg12_decoder.h"
   46 
   47 #include "r600_pipe.h"
   48 #include "radeon_video.h"
   49 #include "radeon_uvd.h"
   50 #include "radeon_vce.h"
   51 #include "r600d.h"
   52 
   53 #define R600_UVD_ENABLE_TILING 0
   54 
   55 /**
   56  * creates an video buffer with an UVD compatible memory layout
   57  */
   58 struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
   59                            const struct pipe_video_buffer *tmpl)
   60 {
   61     struct r600_context *ctx = (struct r600_context *)pipe;
   62     struct r600_texture *resources[VL_NUM_COMPONENTS] = {};
   63     struct radeon_surf* surfaces[VL_NUM_COMPONENTS] = {};
   64     struct pb_buffer **pbs[VL_NUM_COMPONENTS] = {};
   65     enum pipe_format resource_formats[3];
   66     struct pipe_video_buffer template;
   67     struct pipe_resource templ;
   68     unsigned i, array_size;
   69 
   70     assert(pipe);
   71 
   72     /* first create the needed resources as "normal" textures */
   73     vl_get_video_buffer_formats(pipe->screen, tmpl->buffer_format, resource_formats);
   74 
   75     array_size = tmpl->interlaced ? 2 : 1;
   76     template = *tmpl;
   77     template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
   78     template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);
   79 
   80     vl_video_buffer_template(&templ, &template, resource_formats[0], 1, array_size, PIPE_USAGE_DEFAULT, 0);
   81     if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)
   82         templ.bind = PIPE_BIND_LINEAR;
   83     resources[0] = (struct r600_texture *)
   84         pipe->screen->resource_create(pipe->screen, &templ);
   85     if (!resources[0])
   86         goto error;
   87 
   88     if (resource_formats[1] != PIPE_FORMAT_NONE) {
   89         vl_video_buffer_template(&templ, &template, resource_formats[1], 1, array_size, PIPE_USAGE_DEFAULT, 1);
   90         if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)
   91             templ.bind = PIPE_BIND_LINEAR;
   92         resources[1] = (struct r600_texture *)
   93             pipe->screen->resource_create(pipe->screen, &templ);
   94         if (!resources[1])
   95             goto error;
   96     }
   97 
   98     if (resource_formats[2] != PIPE_FORMAT_NONE) {
   99         vl_video_buffer_template(&templ, &template, resource_formats[2], 1, array_size, PIPE_USAGE_DEFAULT, 2);
  100         if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)
  101             templ.bind = PIPE_BIND_LINEAR;
  102         resources[2] = (struct r600_texture *)
  103             pipe->screen->resource_create(pipe->screen, &templ);
  104         if (!resources[2])
  105             goto error;
  106     }
  107 
  108     for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
  109         if (!resources[i])
  110             continue;
  111 
  112         pbs[i] = &resources[i]->resource.buf;
  113         surfaces[i] = &resources[i]->surface;
  114     }
  115 
  116     rvid_join_surfaces(&ctx->b, pbs, surfaces);
  117 
  118     for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
  119         if (!resources[i])
  120             continue;
  121 
  122         /* reset the address */
  123         resources[i]->resource.gpu_address = ctx->b.ws->buffer_get_virtual_address(
  124             resources[i]->resource.buf);
  125     }
  126 
  127     template.height *= array_size;
  128     return vl_video_buffer_create_ex2(pipe, &template, (struct pipe_resource **)resources);
  129 
  130 error:
  131     for (i = 0; i < VL_NUM_COMPONENTS; ++i)
  132         r600_texture_reference(&resources[i], NULL);
  133 
  134     return NULL;
  135 }
  136 
  137 /* hw encode the number of memory banks */
  138 static uint32_t eg_num_banks(uint32_t nbanks)
  139 {
  140     switch (nbanks) {
  141     case 2:
  142         return 0;
  143     case 4:
  144         return 1;
  145     case 8:
  146     default:
  147         return 2;
  148     case 16:
  149         return 3;
  150     }
  151 }
  152 
  153 /* set the decoding target buffer offsets */
  154 static struct pb_buffer* r600_uvd_set_dtb(struct ruvd_msg *msg, struct vl_video_buffer *buf)
  155 {
  156     struct r600_screen *rscreen = (struct r600_screen*)buf->base.context->screen;
  157     struct r600_texture *luma = (struct r600_texture *)buf->resources[0];
  158     struct r600_texture *chroma = (struct r600_texture *)buf->resources[1];
  159 
  160     msg->body.decode.dt_field_mode = buf->base.interlaced;
  161     msg->body.decode.dt_surf_tile_config |= RUVD_NUM_BANKS(eg_num_banks(rscreen->b.info.r600_num_banks));
  162 
  163     ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface);
  164 
  165     return luma->resource.buf;
  166 }
  167 
  168 /* get the radeon resources for VCE */
  169 static void r600_vce_get_buffer(struct pipe_resource *resource,
  170                 struct pb_buffer **handle,
  171                 struct radeon_surf **surface)
  172 {
  173     struct r600_texture *res = (struct r600_texture *)resource;
  174 
  175     if (handle)
  176         *handle = res->resource.buf;
  177 
  178     if (surface)
  179         *surface = &res->surface;
  180 }
  181 
  182 /* create decoder */
  183 struct pipe_video_codec *r600_uvd_create_decoder(struct pipe_context *context,
  184                          const struct pipe_video_codec *templat)
  185 {
  186     struct r600_context *ctx = (struct r600_context *)context;
  187 
  188         if (templat->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)
  189                 return rvce_create_encoder(context, templat, ctx->b.ws, r600_vce_get_buffer);
  190 
  191     return ruvd_create_decoder(context, templat, r600_uvd_set_dtb);
  192 }