vl_video_buffer.c revision 9f9628c72bb16d7d64c9b38671dff8eabd2e7681
13a2b906805985e0a4258bcbaed4cdff758875514Christian König/**************************************************************************
23a2b906805985e0a4258bcbaed4cdff758875514Christian König *
33a2b906805985e0a4258bcbaed4cdff758875514Christian König * Copyright 2011 Christian König.
43a2b906805985e0a4258bcbaed4cdff758875514Christian König * All Rights Reserved.
53a2b906805985e0a4258bcbaed4cdff758875514Christian König *
63a2b906805985e0a4258bcbaed4cdff758875514Christian König * Permission is hereby granted, free of charge, to any person obtaining a
73a2b906805985e0a4258bcbaed4cdff758875514Christian König * copy of this software and associated documentation files (the
83a2b906805985e0a4258bcbaed4cdff758875514Christian König * "Software"), to deal in the Software without restriction, including
93a2b906805985e0a4258bcbaed4cdff758875514Christian König * without limitation the rights to use, copy, modify, merge, publish,
103a2b906805985e0a4258bcbaed4cdff758875514Christian König * distribute, sub license, and/or sell copies of the Software, and to
113a2b906805985e0a4258bcbaed4cdff758875514Christian König * permit persons to whom the Software is furnished to do so, subject to
123a2b906805985e0a4258bcbaed4cdff758875514Christian König * the following conditions:
133a2b906805985e0a4258bcbaed4cdff758875514Christian König *
143a2b906805985e0a4258bcbaed4cdff758875514Christian König * The above copyright notice and this permission notice (including the
153a2b906805985e0a4258bcbaed4cdff758875514Christian König * next paragraph) shall be included in all copies or substantial portions
163a2b906805985e0a4258bcbaed4cdff758875514Christian König * of the Software.
173a2b906805985e0a4258bcbaed4cdff758875514Christian König *
183a2b906805985e0a4258bcbaed4cdff758875514Christian König * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
193a2b906805985e0a4258bcbaed4cdff758875514Christian König * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
203a2b906805985e0a4258bcbaed4cdff758875514Christian König * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
213a2b906805985e0a4258bcbaed4cdff758875514Christian König * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
223a2b906805985e0a4258bcbaed4cdff758875514Christian König * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
233a2b906805985e0a4258bcbaed4cdff758875514Christian König * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
243a2b906805985e0a4258bcbaed4cdff758875514Christian König * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
253a2b906805985e0a4258bcbaed4cdff758875514Christian König *
263a2b906805985e0a4258bcbaed4cdff758875514Christian König **************************************************************************/
273a2b906805985e0a4258bcbaed4cdff758875514Christian König
283a2b906805985e0a4258bcbaed4cdff758875514Christian König#include <assert.h>
293a2b906805985e0a4258bcbaed4cdff758875514Christian König
3019bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "pipe/p_screen.h"
3119bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "pipe/p_context.h"
3219bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "pipe/p_state.h"
333a2b906805985e0a4258bcbaed4cdff758875514Christian König
3419bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_format.h"
3519bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_inlines.h"
3619bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_sampler.h"
3719bcd21ed151cf1716f2f87dff0f712231aa2ce7Kai Wasserbäch#include "util/u_memory.h"
383a2b906805985e0a4258bcbaed4cdff758875514Christian König
39d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König#include "vl_video_buffer.h"
403a2b906805985e0a4258bcbaed4cdff758875514Christian König
4100b4e48560f4d576b7b1924257322f5167e58c8dChristian Königconst enum pipe_format const_resource_formats_YV12[3] = {
4200b4e48560f4d576b7b1924257322f5167e58c8dChristian König   PIPE_FORMAT_R8_UNORM,
4300b4e48560f4d576b7b1924257322f5167e58c8dChristian König   PIPE_FORMAT_R8_UNORM,
4400b4e48560f4d576b7b1924257322f5167e58c8dChristian König   PIPE_FORMAT_R8_UNORM
4500b4e48560f4d576b7b1924257322f5167e58c8dChristian König};
4600b4e48560f4d576b7b1924257322f5167e58c8dChristian König
4700b4e48560f4d576b7b1924257322f5167e58c8dChristian Königconst enum pipe_format const_resource_formats_NV12[3] = {
4800b4e48560f4d576b7b1924257322f5167e58c8dChristian König   PIPE_FORMAT_R8_UNORM,
4900b4e48560f4d576b7b1924257322f5167e58c8dChristian König   PIPE_FORMAT_R8G8_UNORM,
5000b4e48560f4d576b7b1924257322f5167e58c8dChristian König   PIPE_FORMAT_NONE
5100b4e48560f4d576b7b1924257322f5167e58c8dChristian König};
5200b4e48560f4d576b7b1924257322f5167e58c8dChristian König
532eabd05b7525f081ec203747a436d597ce33eb3bChristian Königconst unsigned const_resource_plane_order_YUV[3] = {
542eabd05b7525f081ec203747a436d597ce33eb3bChristian König   0,
552eabd05b7525f081ec203747a436d597ce33eb3bChristian König   1,
562eabd05b7525f081ec203747a436d597ce33eb3bChristian König   2
572eabd05b7525f081ec203747a436d597ce33eb3bChristian König};
582eabd05b7525f081ec203747a436d597ce33eb3bChristian König
592eabd05b7525f081ec203747a436d597ce33eb3bChristian Königconst unsigned const_resource_plane_order_YVU[3] = {
602eabd05b7525f081ec203747a436d597ce33eb3bChristian König   0,
612eabd05b7525f081ec203747a436d597ce33eb3bChristian König   2,
622eabd05b7525f081ec203747a436d597ce33eb3bChristian König   1
632eabd05b7525f081ec203747a436d597ce33eb3bChristian König};
642eabd05b7525f081ec203747a436d597ce33eb3bChristian König
6500b4e48560f4d576b7b1924257322f5167e58c8dChristian Königconst enum pipe_format *
667eca76952b6726be9459375dde7478a01789577eChristian Königvl_video_buffer_formats(struct pipe_screen *screen, enum pipe_format format)
6700b4e48560f4d576b7b1924257322f5167e58c8dChristian König{
6800b4e48560f4d576b7b1924257322f5167e58c8dChristian König   switch(format) {
6900b4e48560f4d576b7b1924257322f5167e58c8dChristian König   case PIPE_FORMAT_YV12:
7000b4e48560f4d576b7b1924257322f5167e58c8dChristian König      return const_resource_formats_YV12;
7100b4e48560f4d576b7b1924257322f5167e58c8dChristian König
7200b4e48560f4d576b7b1924257322f5167e58c8dChristian König   case PIPE_FORMAT_NV12:
7300b4e48560f4d576b7b1924257322f5167e58c8dChristian König      return const_resource_formats_NV12;
7400b4e48560f4d576b7b1924257322f5167e58c8dChristian König
7500b4e48560f4d576b7b1924257322f5167e58c8dChristian König   default:
7600b4e48560f4d576b7b1924257322f5167e58c8dChristian König      return NULL;
7700b4e48560f4d576b7b1924257322f5167e58c8dChristian König   }
7800b4e48560f4d576b7b1924257322f5167e58c8dChristian König}
7900b4e48560f4d576b7b1924257322f5167e58c8dChristian König
802eabd05b7525f081ec203747a436d597ce33eb3bChristian Königconst unsigned *
812eabd05b7525f081ec203747a436d597ce33eb3bChristian Königvl_video_buffer_plane_order(enum pipe_format format)
822eabd05b7525f081ec203747a436d597ce33eb3bChristian König{
832eabd05b7525f081ec203747a436d597ce33eb3bChristian König    switch(format) {
842eabd05b7525f081ec203747a436d597ce33eb3bChristian König   case PIPE_FORMAT_YV12:
852eabd05b7525f081ec203747a436d597ce33eb3bChristian König      return const_resource_plane_order_YVU;
862eabd05b7525f081ec203747a436d597ce33eb3bChristian König
872eabd05b7525f081ec203747a436d597ce33eb3bChristian König   case PIPE_FORMAT_NV12:
882eabd05b7525f081ec203747a436d597ce33eb3bChristian König      return const_resource_plane_order_YUV;
892eabd05b7525f081ec203747a436d597ce33eb3bChristian König
902eabd05b7525f081ec203747a436d597ce33eb3bChristian König   default:
912eabd05b7525f081ec203747a436d597ce33eb3bChristian König      return NULL;
922eabd05b7525f081ec203747a436d597ce33eb3bChristian König   }
932eabd05b7525f081ec203747a436d597ce33eb3bChristian König}
942eabd05b7525f081ec203747a436d597ce33eb3bChristian König
957eca76952b6726be9459375dde7478a01789577eChristian Königboolean
967eca76952b6726be9459375dde7478a01789577eChristian Königvl_video_buffer_is_format_supported(struct pipe_screen *screen,
977eca76952b6726be9459375dde7478a01789577eChristian König                                    enum pipe_format format,
987eca76952b6726be9459375dde7478a01789577eChristian König                                    enum pipe_video_profile profile)
997eca76952b6726be9459375dde7478a01789577eChristian König{
1007eca76952b6726be9459375dde7478a01789577eChristian König   const enum pipe_format *resource_formats;
1017eca76952b6726be9459375dde7478a01789577eChristian König   unsigned i;
1027eca76952b6726be9459375dde7478a01789577eChristian König
1037eca76952b6726be9459375dde7478a01789577eChristian König   resource_formats = vl_video_buffer_formats(screen, format);
1047eca76952b6726be9459375dde7478a01789577eChristian König   if (!resource_formats)
1057eca76952b6726be9459375dde7478a01789577eChristian König      return false;
1067eca76952b6726be9459375dde7478a01789577eChristian König
10702e191cb6aa13286fff956a7929959d7cee7241dEmeric Grange   for (i = 0; i < VL_MAX_PLANES; ++i) {
1087eca76952b6726be9459375dde7478a01789577eChristian König      if (!resource_formats[i])
1097eca76952b6726be9459375dde7478a01789577eChristian König         continue;
1107eca76952b6726be9459375dde7478a01789577eChristian König
1117eca76952b6726be9459375dde7478a01789577eChristian König      if (!screen->is_format_supported(screen, resource_formats[i], PIPE_TEXTURE_2D, 0, PIPE_USAGE_STATIC))
1127eca76952b6726be9459375dde7478a01789577eChristian König         return false;
1137eca76952b6726be9459375dde7478a01789577eChristian König   }
1147eca76952b6726be9459375dde7478a01789577eChristian König
1157eca76952b6726be9459375dde7478a01789577eChristian König   return true;
1167eca76952b6726be9459375dde7478a01789577eChristian König}
1177eca76952b6726be9459375dde7478a01789577eChristian König
118efc7fda4627919b5355952d955ee4a2c98505e56Christian Königunsigned
119efc7fda4627919b5355952d955ee4a2c98505e56Christian Königvl_video_buffer_max_size(struct pipe_screen *screen)
120efc7fda4627919b5355952d955ee4a2c98505e56Christian König{
121efc7fda4627919b5355952d955ee4a2c98505e56Christian König   uint32_t max_2d_texture_level;
122efc7fda4627919b5355952d955ee4a2c98505e56Christian König
123efc7fda4627919b5355952d955ee4a2c98505e56Christian König   max_2d_texture_level = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
124efc7fda4627919b5355952d955ee4a2c98505e56Christian König
125efc7fda4627919b5355952d955ee4a2c98505e56Christian König   return 1 << (max_2d_texture_level-1);
126efc7fda4627919b5355952d955ee4a2c98505e56Christian König}
127efc7fda4627919b5355952d955ee4a2c98505e56Christian König
1288c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian Königvoid
1298c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian Königvl_video_buffer_set_associated_data(struct pipe_video_buffer *vbuf,
1308c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König                                    struct pipe_video_decoder *vdec,
1318c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König                                    void *associated_data,
1328c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König                                    void (*destroy_associated_data)(void *))
1338c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König{
1348c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König   vbuf->decoder = vdec;
1358c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König
1368c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König   if (vbuf->associated_data == associated_data)
1378c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König      return;
1388c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König
1398c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König   if (vbuf->associated_data)
1408c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König      vbuf->destroy_associated_data(vbuf->associated_data);
1418c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König
1428c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König   vbuf->associated_data = associated_data;
1438c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König   vbuf->destroy_associated_data = destroy_associated_data;
1448c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König}
1458c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König
1468c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian Königvoid *
1478c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian Königvl_video_buffer_get_associated_data(struct pipe_video_buffer *vbuf,
1488c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König                                    struct pipe_video_decoder *vdec)
1498c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König{
1508c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König   if (vbuf->decoder == vdec)
1518c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König      return vbuf->associated_data;
1528c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König   else
1538c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König      return NULL;
1548c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König}
1558c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König
15612b49ca2dfab832ff9dce50c846aee7f3efc3084Christian Königvoid
15712b49ca2dfab832ff9dce50c846aee7f3efc3084Christian Königvl_vide_buffer_template(struct pipe_resource *templ,
15812b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König                        const struct pipe_video_buffer *tmpl,
15912b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König                        enum pipe_format resource_format,
16012b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König                        unsigned depth, unsigned usage, unsigned plane)
16112b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König{
16212b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   memset(templ, 0, sizeof(*templ));
16312b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   templ->target = depth > 1 ? PIPE_TEXTURE_3D : PIPE_TEXTURE_2D;
16412b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   templ->format = resource_format;
16512b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   templ->width0 = tmpl->width;
16612b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   templ->height0 = tmpl->height;
16712b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   templ->depth0 = depth;
16812b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   templ->array_size = 1;
16912b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   templ->bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
17012b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   templ->usage = usage;
17112b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König
17212b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   if (plane > 0) {
17312b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König      if (tmpl->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
17412b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König         templ->width0 /= 2;
17512b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König         templ->height0 /= 2;
17612b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König      } else if (tmpl->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
17712b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König         templ->height0 /= 2;
17812b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König      }
17912b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   }
18012b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König}
18112b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König
182d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic void
183d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königvl_video_buffer_destroy(struct pipe_video_buffer *buffer)
184d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
185d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
186d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   unsigned i;
187d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
188d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(buf);
189d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
190d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < VL_MAX_PLANES; ++i) {
1913ea7e2713c836f23d59c4034385609e371a94c8dChristian König      pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
1923ea7e2713c836f23d59c4034385609e371a94c8dChristian König      pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
193d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      pipe_resource_reference(&buf->resources[i], NULL);
194d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   }
1959af70c90dba9ed9902778883b675062fa0168b48Christian König
1969af70c90dba9ed9902778883b675062fa0168b48Christian König   for (i = 0; i < VL_MAX_PLANES * 2; ++i)
1979af70c90dba9ed9902778883b675062fa0168b48Christian König      pipe_surface_reference(&buf->surfaces[i], NULL);
1989af70c90dba9ed9902778883b675062fa0168b48Christian König
1998c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König   vl_video_buffer_set_associated_data(buffer, NULL, NULL, NULL);
200df5e0b9435c869f88234a69db9bfe97342b027d4Christian König
201df5e0b9435c869f88234a69db9bfe97342b027d4Christian König   FREE(buffer);
202d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
203d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
204d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic struct pipe_sampler_view **
2053ea7e2713c836f23d59c4034385609e371a94c8dChristian Königvl_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
2063a2b906805985e0a4258bcbaed4cdff758875514Christian König{
207d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
2083a2b906805985e0a4258bcbaed4cdff758875514Christian König   struct pipe_sampler_view sv_templ;
2093a2b906805985e0a4258bcbaed4cdff758875514Christian König   struct pipe_context *pipe;
2103a2b906805985e0a4258bcbaed4cdff758875514Christian König   unsigned i;
2113a2b906805985e0a4258bcbaed4cdff758875514Christian König
212d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(buf);
2133a2b906805985e0a4258bcbaed4cdff758875514Christian König
2144e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   pipe = buf->base.context;
2153a2b906805985e0a4258bcbaed4cdff758875514Christian König
216d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < buf->num_planes; ++i ) {
2173ea7e2713c836f23d59c4034385609e371a94c8dChristian König      if (!buf->sampler_view_planes[i]) {
2183a2b906805985e0a4258bcbaed4cdff758875514Christian König         memset(&sv_templ, 0, sizeof(sv_templ));
219d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König         u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format);
2203ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2213ea7e2713c836f23d59c4034385609e371a94c8dChristian König         if (util_format_get_nr_components(buf->resources[i]->format) == 1)
2223ea7e2713c836f23d59c4034385609e371a94c8dChristian König            sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = sv_templ.swizzle_a = PIPE_SWIZZLE_RED;
2233ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2243ea7e2713c836f23d59c4034385609e371a94c8dChristian König         buf->sampler_view_planes[i] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ);
2253ea7e2713c836f23d59c4034385609e371a94c8dChristian König         if (!buf->sampler_view_planes[i])
2263a2b906805985e0a4258bcbaed4cdff758875514Christian König            goto error;
2273a2b906805985e0a4258bcbaed4cdff758875514Christian König      }
2283a2b906805985e0a4258bcbaed4cdff758875514Christian König   }
2293a2b906805985e0a4258bcbaed4cdff758875514Christian König
2303ea7e2713c836f23d59c4034385609e371a94c8dChristian König   return buf->sampler_view_planes;
2313a2b906805985e0a4258bcbaed4cdff758875514Christian König
2323a2b906805985e0a4258bcbaed4cdff758875514Christian Königerror:
233d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < buf->num_planes; ++i )
2343ea7e2713c836f23d59c4034385609e371a94c8dChristian König      pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
2353ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2363ea7e2713c836f23d59c4034385609e371a94c8dChristian König   return NULL;
2373ea7e2713c836f23d59c4034385609e371a94c8dChristian König}
2383ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2393ea7e2713c836f23d59c4034385609e371a94c8dChristian Königstatic struct pipe_sampler_view **
2403ea7e2713c836f23d59c4034385609e371a94c8dChristian Königvl_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
2413ea7e2713c836f23d59c4034385609e371a94c8dChristian König{
2423ea7e2713c836f23d59c4034385609e371a94c8dChristian König   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
2433ea7e2713c836f23d59c4034385609e371a94c8dChristian König   struct pipe_sampler_view sv_templ;
2443ea7e2713c836f23d59c4034385609e371a94c8dChristian König   struct pipe_context *pipe;
2452eabd05b7525f081ec203747a436d597ce33eb3bChristian König   const unsigned *plane_order;
2463ea7e2713c836f23d59c4034385609e371a94c8dChristian König   unsigned i, j, component;
2473ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2483ea7e2713c836f23d59c4034385609e371a94c8dChristian König   assert(buf);
2493ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2504e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   pipe = buf->base.context;
2513ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2522eabd05b7525f081ec203747a436d597ce33eb3bChristian König   plane_order = vl_video_buffer_plane_order(buf->base.buffer_format);
2532eabd05b7525f081ec203747a436d597ce33eb3bChristian König
2543ea7e2713c836f23d59c4034385609e371a94c8dChristian König   for (component = 0, i = 0; i < buf->num_planes; ++i ) {
2552eabd05b7525f081ec203747a436d597ce33eb3bChristian König      struct pipe_resource *res = buf->resources[plane_order[i]];
2562eabd05b7525f081ec203747a436d597ce33eb3bChristian König      unsigned nr_components = util_format_get_nr_components(res->format);
2573ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2583ea7e2713c836f23d59c4034385609e371a94c8dChristian König      for (j = 0; j < nr_components; ++j, ++component) {
2593ea7e2713c836f23d59c4034385609e371a94c8dChristian König         assert(component < VL_MAX_PLANES);
2603ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2613ea7e2713c836f23d59c4034385609e371a94c8dChristian König         if (!buf->sampler_view_components[component]) {
2623ea7e2713c836f23d59c4034385609e371a94c8dChristian König            memset(&sv_templ, 0, sizeof(sv_templ));
2632eabd05b7525f081ec203747a436d597ce33eb3bChristian König            u_sampler_view_default_template(&sv_templ, res, res->format);
2643ea7e2713c836f23d59c4034385609e371a94c8dChristian König            sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
2653ea7e2713c836f23d59c4034385609e371a94c8dChristian König            sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
2662eabd05b7525f081ec203747a436d597ce33eb3bChristian König            buf->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
2673ea7e2713c836f23d59c4034385609e371a94c8dChristian König            if (!buf->sampler_view_components[component])
2683ea7e2713c836f23d59c4034385609e371a94c8dChristian König               goto error;
2693ea7e2713c836f23d59c4034385609e371a94c8dChristian König         }
2703ea7e2713c836f23d59c4034385609e371a94c8dChristian König      }
2713ea7e2713c836f23d59c4034385609e371a94c8dChristian König   }
2723ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2733ea7e2713c836f23d59c4034385609e371a94c8dChristian König   return buf->sampler_view_components;
2743ea7e2713c836f23d59c4034385609e371a94c8dChristian König
2753ea7e2713c836f23d59c4034385609e371a94c8dChristian Königerror:
2763ea7e2713c836f23d59c4034385609e371a94c8dChristian König   for (i = 0; i < VL_MAX_PLANES; ++i )
2773ea7e2713c836f23d59c4034385609e371a94c8dChristian König      pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
2783a2b906805985e0a4258bcbaed4cdff758875514Christian König
2793a2b906805985e0a4258bcbaed4cdff758875514Christian König   return NULL;
2803a2b906805985e0a4258bcbaed4cdff758875514Christian König}
2813a2b906805985e0a4258bcbaed4cdff758875514Christian König
282d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic struct pipe_surface **
283d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königvl_video_buffer_surfaces(struct pipe_video_buffer *buffer)
2843a2b906805985e0a4258bcbaed4cdff758875514Christian König{
285d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
2863a2b906805985e0a4258bcbaed4cdff758875514Christian König   struct pipe_surface surf_templ;
2873a2b906805985e0a4258bcbaed4cdff758875514Christian König   struct pipe_context *pipe;
2889f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König   unsigned i, j, depth, surf;
2893a2b906805985e0a4258bcbaed4cdff758875514Christian König
290d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(buf);
2913a2b906805985e0a4258bcbaed4cdff758875514Christian König
2924e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   pipe = buf->base.context;
2933a2b906805985e0a4258bcbaed4cdff758875514Christian König
2949f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König   depth = buffer->interlaced ? 2 : 1;
2959f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König   for (i = 0, surf = 0; i < depth; ++i ) {
2969f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König      for (j = 0; j < VL_MAX_PLANES; ++j, ++surf) {
2979af70c90dba9ed9902778883b675062fa0168b48Christian König         assert(surf < (VL_MAX_PLANES * 2));
2989af70c90dba9ed9902778883b675062fa0168b48Christian König
2999f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König         if (!buf->resources[j]) {
3009f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König            pipe_surface_reference(&buf->surfaces[surf], NULL);
3019f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König            continue;
3029f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König         }
3039f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König
3049af70c90dba9ed9902778883b675062fa0168b48Christian König         if (!buf->surfaces[surf]) {
3059af70c90dba9ed9902778883b675062fa0168b48Christian König            memset(&surf_templ, 0, sizeof(surf_templ));
3069f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König            surf_templ.format = buf->resources[j]->format;
3079af70c90dba9ed9902778883b675062fa0168b48Christian König            surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
3089f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König            surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = i;
3099f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König            buf->surfaces[surf] = pipe->create_surface(pipe, buf->resources[j], &surf_templ);
3109f9628c72bb16d7d64c9b38671dff8eabd2e7681Christian König            if (!buf->surfaces[surf])
3119af70c90dba9ed9902778883b675062fa0168b48Christian König               goto error;
3129af70c90dba9ed9902778883b675062fa0168b48Christian König         }
3133a2b906805985e0a4258bcbaed4cdff758875514Christian König      }
3143a2b906805985e0a4258bcbaed4cdff758875514Christian König   }
3153a2b906805985e0a4258bcbaed4cdff758875514Christian König
316d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return buf->surfaces;
3173a2b906805985e0a4258bcbaed4cdff758875514Christian König
3183a2b906805985e0a4258bcbaed4cdff758875514Christian Königerror:
3199af70c90dba9ed9902778883b675062fa0168b48Christian König   for (i = 0; i < (VL_MAX_PLANES * 2); ++i )
320d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      pipe_surface_reference(&buf->surfaces[i], NULL);
3213a2b906805985e0a4258bcbaed4cdff758875514Christian König
3223a2b906805985e0a4258bcbaed4cdff758875514Christian König   return NULL;
3233a2b906805985e0a4258bcbaed4cdff758875514Christian König}
3243a2b906805985e0a4258bcbaed4cdff758875514Christian König
325d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstruct pipe_video_buffer *
3264e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian Königvl_video_buffer_create(struct pipe_context *pipe,
327e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König                       const struct pipe_video_buffer *tmpl)
3284e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König{
3294e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   const enum pipe_format *resource_formats;
3304ccae0dfaaee5f773fb356d052e6605ea0d99c2cChristian König   struct pipe_video_buffer templat, *result;
3314e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   bool pot_buffers;
3324e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
3334e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   assert(pipe);
334e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   assert(tmpl->width > 0 && tmpl->height > 0);
3354e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
3364e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   pot_buffers = !pipe->screen->get_video_param
3374e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   (
3384e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      pipe->screen,
3394e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      PIPE_VIDEO_PROFILE_UNKNOWN,
3404e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      PIPE_VIDEO_CAP_NPOT_TEXTURES
3414e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   );
3424e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
343e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   resource_formats = vl_video_buffer_formats(pipe->screen, tmpl->buffer_format);
3444e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   if (!resource_formats)
3454e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      return NULL;
3464e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
347e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   templat = *tmpl;
348e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   templat.width = pot_buffers ? util_next_power_of_two(tmpl->width)
349e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König                 : align(tmpl->width, MACROBLOCK_WIDTH);
350e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   templat.height = pot_buffers ? util_next_power_of_two(tmpl->height)
351e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König                  : align(tmpl->height, MACROBLOCK_HEIGHT);
3524e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
3539af70c90dba9ed9902778883b675062fa0168b48Christian König   if (tmpl->interlaced)
3549af70c90dba9ed9902778883b675062fa0168b48Christian König      templat.height /= 2;
3559af70c90dba9ed9902778883b675062fa0168b48Christian König
3564ccae0dfaaee5f773fb356d052e6605ea0d99c2cChristian König   result = vl_video_buffer_create_ex
3574e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   (
358e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König      pipe, &templat, resource_formats,
3599af70c90dba9ed9902778883b675062fa0168b48Christian König      tmpl->interlaced ? 2 : 1, PIPE_USAGE_STATIC
3604e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   );
3614ccae0dfaaee5f773fb356d052e6605ea0d99c2cChristian König
3624ccae0dfaaee5f773fb356d052e6605ea0d99c2cChristian König
3634ccae0dfaaee5f773fb356d052e6605ea0d99c2cChristian König   if (result && tmpl->interlaced)
3644ccae0dfaaee5f773fb356d052e6605ea0d99c2cChristian König      result->height *= 2;
3654ccae0dfaaee5f773fb356d052e6605ea0d99c2cChristian König
3664ccae0dfaaee5f773fb356d052e6605ea0d99c2cChristian König   return result;
3674e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König}
3684e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
3694e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian Königstruct pipe_video_buffer *
3704e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian Königvl_video_buffer_create_ex(struct pipe_context *pipe,
371e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König                          const struct pipe_video_buffer *tmpl,
3724e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König                          const enum pipe_format resource_formats[VL_MAX_PLANES],
373e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König                          unsigned depth, unsigned usage)
3743a2b906805985e0a4258bcbaed4cdff758875514Christian König{
375455090c4c42cc7003594a750105980b125e140d4José Fonseca   struct pipe_resource res_tmpl;
376455090c4c42cc7003594a750105980b125e140d4José Fonseca   struct pipe_resource *resources[VL_MAX_PLANES];
3773a2b906805985e0a4258bcbaed4cdff758875514Christian König   unsigned i;
3783a2b906805985e0a4258bcbaed4cdff758875514Christian König
3794e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   assert(pipe);
380d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
381455090c4c42cc7003594a750105980b125e140d4José Fonseca   memset(resources, 0, sizeof resources);
382455090c4c42cc7003594a750105980b125e140d4José Fonseca
38312b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[0], depth, usage, 0);
38412b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   resources[0] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
38512b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   if (!resources[0])
386d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      goto error;
387d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
3884f3fb1586aebfe248321e935651b5af92b5a8261Christian König   if (resource_formats[1] == PIPE_FORMAT_NONE) {
389e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König      assert(tmpl->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444);
3904f3fb1586aebfe248321e935651b5af92b5a8261Christian König      assert(resource_formats[2] == PIPE_FORMAT_NONE);
39112b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König      return vl_video_buffer_create_ex2(pipe, tmpl, resources);
3923a2b906805985e0a4258bcbaed4cdff758875514Christian König   }
393d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
39412b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[1], depth, usage, 1);
39512b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   resources[1] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
39612b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   if (!resources[1])
397d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      goto error;
398d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
3994f3fb1586aebfe248321e935651b5af92b5a8261Christian König   if (resource_formats[2] == PIPE_FORMAT_NONE)
40012b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König      return vl_video_buffer_create_ex2(pipe, tmpl, resources);
401d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
40212b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[2], depth, usage, 2);
40312b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   resources[2] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
40412b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   if (!resources[2])
405d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      goto error;
406d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
40712b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   return vl_video_buffer_create_ex2(pipe, tmpl, resources);
408d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
409d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königerror:
410d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < VL_MAX_PLANES; ++i)
41112b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König      pipe_resource_reference(&resources[i], NULL);
412d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
413d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return NULL;
4143a2b906805985e0a4258bcbaed4cdff758875514Christian König}
41512b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König
41612b49ca2dfab832ff9dce50c846aee7f3efc3084Christian Königstruct pipe_video_buffer *
41712b49ca2dfab832ff9dce50c846aee7f3efc3084Christian Königvl_video_buffer_create_ex2(struct pipe_context *pipe,
41812b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König                           const struct pipe_video_buffer *tmpl,
41912b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König                           struct pipe_resource *resources[VL_MAX_PLANES])
42012b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König{
42112b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   struct vl_video_buffer *buffer;
42212b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   unsigned i;
42312b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König
42412b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   buffer = CALLOC_STRUCT(vl_video_buffer);
42512b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König
42612b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   buffer->base = *tmpl;
42712b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   buffer->base.context = pipe;
42812b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   buffer->base.destroy = vl_video_buffer_destroy;
42912b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   buffer->base.get_sampler_view_planes = vl_video_buffer_sampler_view_planes;
43012b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   buffer->base.get_sampler_view_components = vl_video_buffer_sampler_view_components;
43112b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   buffer->base.get_surfaces = vl_video_buffer_surfaces;
43212b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   buffer->num_planes = 0;
43312b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König
43412b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   for (i = 0; i < VL_MAX_PLANES; ++i) {
43512b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König      buffer->resources[i] = resources[i];
43612b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König      if (resources[i])
43712b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König         buffer->num_planes++;
43812b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   }
43912b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König
44012b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König   return &buffer->base;
44112b49ca2dfab832ff9dce50c846aee7f3efc3084Christian König}
442