vl_video_buffer.c revision 19bcd21ed151cf1716f2f87dff0f712231aa2ce7
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
5300b4e48560f4d576b7b1924257322f5167e58c8dChristian Königconst enum pipe_format *
547eca76952b6726be9459375dde7478a01789577eChristian Königvl_video_buffer_formats(struct pipe_screen *screen, enum pipe_format format)
5500b4e48560f4d576b7b1924257322f5167e58c8dChristian König{
5600b4e48560f4d576b7b1924257322f5167e58c8dChristian König   switch(format) {
5700b4e48560f4d576b7b1924257322f5167e58c8dChristian König   case PIPE_FORMAT_YV12:
5800b4e48560f4d576b7b1924257322f5167e58c8dChristian König      return const_resource_formats_YV12;
5900b4e48560f4d576b7b1924257322f5167e58c8dChristian König
6000b4e48560f4d576b7b1924257322f5167e58c8dChristian König   case PIPE_FORMAT_NV12:
6100b4e48560f4d576b7b1924257322f5167e58c8dChristian König      return const_resource_formats_NV12;
6200b4e48560f4d576b7b1924257322f5167e58c8dChristian König
6300b4e48560f4d576b7b1924257322f5167e58c8dChristian König   default:
6400b4e48560f4d576b7b1924257322f5167e58c8dChristian König      return NULL;
6500b4e48560f4d576b7b1924257322f5167e58c8dChristian König   }
6600b4e48560f4d576b7b1924257322f5167e58c8dChristian König}
6700b4e48560f4d576b7b1924257322f5167e58c8dChristian König
687eca76952b6726be9459375dde7478a01789577eChristian Königboolean
697eca76952b6726be9459375dde7478a01789577eChristian Königvl_video_buffer_is_format_supported(struct pipe_screen *screen,
707eca76952b6726be9459375dde7478a01789577eChristian König                                    enum pipe_format format,
717eca76952b6726be9459375dde7478a01789577eChristian König                                    enum pipe_video_profile profile)
727eca76952b6726be9459375dde7478a01789577eChristian König{
737eca76952b6726be9459375dde7478a01789577eChristian König   const enum pipe_format *resource_formats;
747eca76952b6726be9459375dde7478a01789577eChristian König   unsigned i;
757eca76952b6726be9459375dde7478a01789577eChristian König
767eca76952b6726be9459375dde7478a01789577eChristian König   resource_formats = vl_video_buffer_formats(screen, format);
777eca76952b6726be9459375dde7478a01789577eChristian König   if (!resource_formats)
787eca76952b6726be9459375dde7478a01789577eChristian König      return false;
797eca76952b6726be9459375dde7478a01789577eChristian König
807eca76952b6726be9459375dde7478a01789577eChristian König   for(i = 0; i < VL_MAX_PLANES; ++i) {
817eca76952b6726be9459375dde7478a01789577eChristian König      if (!resource_formats[i])
827eca76952b6726be9459375dde7478a01789577eChristian König         continue;
837eca76952b6726be9459375dde7478a01789577eChristian König
847eca76952b6726be9459375dde7478a01789577eChristian König      if (!screen->is_format_supported(screen, resource_formats[i], PIPE_TEXTURE_2D, 0, PIPE_USAGE_STATIC))
857eca76952b6726be9459375dde7478a01789577eChristian König         return false;
867eca76952b6726be9459375dde7478a01789577eChristian König   }
877eca76952b6726be9459375dde7478a01789577eChristian König
887eca76952b6726be9459375dde7478a01789577eChristian König   return true;
897eca76952b6726be9459375dde7478a01789577eChristian König}
907eca76952b6726be9459375dde7478a01789577eChristian König
91efc7fda4627919b5355952d955ee4a2c98505e56Christian Königunsigned
92efc7fda4627919b5355952d955ee4a2c98505e56Christian Königvl_video_buffer_max_size(struct pipe_screen *screen)
93efc7fda4627919b5355952d955ee4a2c98505e56Christian König{
94efc7fda4627919b5355952d955ee4a2c98505e56Christian König   uint32_t max_2d_texture_level;
95efc7fda4627919b5355952d955ee4a2c98505e56Christian König
96efc7fda4627919b5355952d955ee4a2c98505e56Christian König   max_2d_texture_level = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
97efc7fda4627919b5355952d955ee4a2c98505e56Christian König
98efc7fda4627919b5355952d955ee4a2c98505e56Christian König   return 1 << (max_2d_texture_level-1);
99efc7fda4627919b5355952d955ee4a2c98505e56Christian König}
100efc7fda4627919b5355952d955ee4a2c98505e56Christian König
101d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic void
102d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königvl_video_buffer_destroy(struct pipe_video_buffer *buffer)
103d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König{
104d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
105d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   unsigned i;
106d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
107d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(buf);
108d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
109d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < VL_MAX_PLANES; ++i) {
110d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      pipe_surface_reference(&buf->surfaces[i], NULL);
1113ea7e2713c836f23d59c4034385609e371a94c8dChristian König      pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
1123ea7e2713c836f23d59c4034385609e371a94c8dChristian König      pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
113d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      pipe_resource_reference(&buf->resources[i], NULL);
114d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   }
115df5e0b9435c869f88234a69db9bfe97342b027d4Christian König
116df5e0b9435c869f88234a69db9bfe97342b027d4Christian König   FREE(buffer);
117d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König}
118d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
119d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic struct pipe_sampler_view **
1203ea7e2713c836f23d59c4034385609e371a94c8dChristian Königvl_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
1213a2b906805985e0a4258bcbaed4cdff758875514Christian König{
122d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
1233a2b906805985e0a4258bcbaed4cdff758875514Christian König   struct pipe_sampler_view sv_templ;
1243a2b906805985e0a4258bcbaed4cdff758875514Christian König   struct pipe_context *pipe;
1253a2b906805985e0a4258bcbaed4cdff758875514Christian König   unsigned i;
1263a2b906805985e0a4258bcbaed4cdff758875514Christian König
127d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(buf);
1283a2b906805985e0a4258bcbaed4cdff758875514Christian König
1294e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   pipe = buf->base.context;
1303a2b906805985e0a4258bcbaed4cdff758875514Christian König
131d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < buf->num_planes; ++i ) {
1323ea7e2713c836f23d59c4034385609e371a94c8dChristian König      if (!buf->sampler_view_planes[i]) {
1333a2b906805985e0a4258bcbaed4cdff758875514Christian König         memset(&sv_templ, 0, sizeof(sv_templ));
134d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König         u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format);
1353ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1363ea7e2713c836f23d59c4034385609e371a94c8dChristian König         if (util_format_get_nr_components(buf->resources[i]->format) == 1)
1373ea7e2713c836f23d59c4034385609e371a94c8dChristian König            sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = sv_templ.swizzle_a = PIPE_SWIZZLE_RED;
1383ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1393ea7e2713c836f23d59c4034385609e371a94c8dChristian König         buf->sampler_view_planes[i] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ);
1403ea7e2713c836f23d59c4034385609e371a94c8dChristian König         if (!buf->sampler_view_planes[i])
1413a2b906805985e0a4258bcbaed4cdff758875514Christian König            goto error;
1423a2b906805985e0a4258bcbaed4cdff758875514Christian König      }
1433a2b906805985e0a4258bcbaed4cdff758875514Christian König   }
1443a2b906805985e0a4258bcbaed4cdff758875514Christian König
1453ea7e2713c836f23d59c4034385609e371a94c8dChristian König   return buf->sampler_view_planes;
1463a2b906805985e0a4258bcbaed4cdff758875514Christian König
1473a2b906805985e0a4258bcbaed4cdff758875514Christian Königerror:
148d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < buf->num_planes; ++i )
1493ea7e2713c836f23d59c4034385609e371a94c8dChristian König      pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
1503ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1513ea7e2713c836f23d59c4034385609e371a94c8dChristian König   return NULL;
1523ea7e2713c836f23d59c4034385609e371a94c8dChristian König}
1533ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1543ea7e2713c836f23d59c4034385609e371a94c8dChristian Königstatic struct pipe_sampler_view **
1553ea7e2713c836f23d59c4034385609e371a94c8dChristian Königvl_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
1563ea7e2713c836f23d59c4034385609e371a94c8dChristian König{
1573ea7e2713c836f23d59c4034385609e371a94c8dChristian König   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
1583ea7e2713c836f23d59c4034385609e371a94c8dChristian König   struct pipe_sampler_view sv_templ;
1593ea7e2713c836f23d59c4034385609e371a94c8dChristian König   struct pipe_context *pipe;
1603ea7e2713c836f23d59c4034385609e371a94c8dChristian König   unsigned i, j, component;
1613ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1623ea7e2713c836f23d59c4034385609e371a94c8dChristian König   assert(buf);
1633ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1644e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   pipe = buf->base.context;
1653ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1663ea7e2713c836f23d59c4034385609e371a94c8dChristian König   for (component = 0, i = 0; i < buf->num_planes; ++i ) {
1673ea7e2713c836f23d59c4034385609e371a94c8dChristian König      unsigned nr_components = util_format_get_nr_components(buf->resources[i]->format);
1683ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1693ea7e2713c836f23d59c4034385609e371a94c8dChristian König      for (j = 0; j < nr_components; ++j, ++component) {
1703ea7e2713c836f23d59c4034385609e371a94c8dChristian König         assert(component < VL_MAX_PLANES);
1713ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1723ea7e2713c836f23d59c4034385609e371a94c8dChristian König         if (!buf->sampler_view_components[component]) {
1733ea7e2713c836f23d59c4034385609e371a94c8dChristian König            memset(&sv_templ, 0, sizeof(sv_templ));
1743ea7e2713c836f23d59c4034385609e371a94c8dChristian König            u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format);
1753ea7e2713c836f23d59c4034385609e371a94c8dChristian König            sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
1763ea7e2713c836f23d59c4034385609e371a94c8dChristian König            sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
1773ea7e2713c836f23d59c4034385609e371a94c8dChristian König            buf->sampler_view_components[component] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ);
1783ea7e2713c836f23d59c4034385609e371a94c8dChristian König            if (!buf->sampler_view_components[component])
1793ea7e2713c836f23d59c4034385609e371a94c8dChristian König               goto error;
1803ea7e2713c836f23d59c4034385609e371a94c8dChristian König         }
1813ea7e2713c836f23d59c4034385609e371a94c8dChristian König      }
1823ea7e2713c836f23d59c4034385609e371a94c8dChristian König   }
1833ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1843ea7e2713c836f23d59c4034385609e371a94c8dChristian König   return buf->sampler_view_components;
1853ea7e2713c836f23d59c4034385609e371a94c8dChristian König
1863ea7e2713c836f23d59c4034385609e371a94c8dChristian Königerror:
1873ea7e2713c836f23d59c4034385609e371a94c8dChristian König   for (i = 0; i < VL_MAX_PLANES; ++i )
1883ea7e2713c836f23d59c4034385609e371a94c8dChristian König      pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
1893a2b906805985e0a4258bcbaed4cdff758875514Christian König
1903a2b906805985e0a4258bcbaed4cdff758875514Christian König   return NULL;
1913a2b906805985e0a4258bcbaed4cdff758875514Christian König}
1923a2b906805985e0a4258bcbaed4cdff758875514Christian König
193d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstatic struct pipe_surface **
194d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königvl_video_buffer_surfaces(struct pipe_video_buffer *buffer)
1953a2b906805985e0a4258bcbaed4cdff758875514Christian König{
196d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
1973a2b906805985e0a4258bcbaed4cdff758875514Christian König   struct pipe_surface surf_templ;
1983a2b906805985e0a4258bcbaed4cdff758875514Christian König   struct pipe_context *pipe;
1993a2b906805985e0a4258bcbaed4cdff758875514Christian König   unsigned i;
2003a2b906805985e0a4258bcbaed4cdff758875514Christian König
201d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   assert(buf);
2023a2b906805985e0a4258bcbaed4cdff758875514Christian König
2034e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   pipe = buf->base.context;
2043a2b906805985e0a4258bcbaed4cdff758875514Christian König
205d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < buf->num_planes; ++i ) {
206d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      if (!buf->surfaces[i]) {
2073a2b906805985e0a4258bcbaed4cdff758875514Christian König         memset(&surf_templ, 0, sizeof(surf_templ));
208d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König         surf_templ.format = buf->resources[i]->format;
2093a2b906805985e0a4258bcbaed4cdff758875514Christian König         surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
210d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König         buf->surfaces[i] = pipe->create_surface(pipe, buf->resources[i], &surf_templ);
211d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König         if (!buf->surfaces[i])
2123a2b906805985e0a4258bcbaed4cdff758875514Christian König            goto error;
2133a2b906805985e0a4258bcbaed4cdff758875514Christian König      }
2143a2b906805985e0a4258bcbaed4cdff758875514Christian König   }
2153a2b906805985e0a4258bcbaed4cdff758875514Christian König
216d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return buf->surfaces;
2173a2b906805985e0a4258bcbaed4cdff758875514Christian König
2183a2b906805985e0a4258bcbaed4cdff758875514Christian Königerror:
219d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < buf->num_planes; ++i )
220d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      pipe_surface_reference(&buf->surfaces[i], NULL);
2213a2b906805985e0a4258bcbaed4cdff758875514Christian König
2223a2b906805985e0a4258bcbaed4cdff758875514Christian König   return NULL;
2233a2b906805985e0a4258bcbaed4cdff758875514Christian König}
2243a2b906805985e0a4258bcbaed4cdff758875514Christian König
225d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königstruct pipe_video_buffer *
2264e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian Königvl_video_buffer_create(struct pipe_context *pipe,
2274e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König                       enum pipe_format buffer_format,
2284e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König                       enum pipe_video_chroma_format chroma_format,
2294e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König                       unsigned width, unsigned height)
2304e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König{
2314e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   const enum pipe_format *resource_formats;
2324e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   struct pipe_video_buffer *result;
2334e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   unsigned buffer_width, buffer_height;
2344e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   bool pot_buffers;
2354e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
2364e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   assert(pipe);
2374e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   assert(width > 0 && height > 0);
2384e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
2394e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   pot_buffers = !pipe->screen->get_video_param
2404e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   (
2414e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      pipe->screen,
2424e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      PIPE_VIDEO_PROFILE_UNKNOWN,
2434e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      PIPE_VIDEO_CAP_NPOT_TEXTURES
2444e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   );
2454e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
2464e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   resource_formats = vl_video_buffer_formats(pipe->screen, buffer_format);
2474e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   if (!resource_formats)
2484e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      return NULL;
2494e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
2504e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   buffer_width = pot_buffers ? util_next_power_of_two(width) : align(width, MACROBLOCK_WIDTH);
2514e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   buffer_height = pot_buffers ? util_next_power_of_two(height) : align(height, MACROBLOCK_HEIGHT);
2524e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
2534e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   result = vl_video_buffer_create_ex
2544e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   (
2554e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      pipe, buffer_width, buffer_height, 1,
2564e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      chroma_format, resource_formats, PIPE_USAGE_STATIC
2574e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   );
2584e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   if (result)
2594e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König      result->buffer_format = buffer_format;
2604e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
2614e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   return result;
2624e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König}
2634e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König
2644e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian Königstruct pipe_video_buffer *
2654e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian Königvl_video_buffer_create_ex(struct pipe_context *pipe,
2664e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König                          unsigned width, unsigned height, unsigned depth,
2674e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König                          enum pipe_video_chroma_format chroma_format,
2684e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König                          const enum pipe_format resource_formats[VL_MAX_PLANES],
2694e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König                          unsigned usage)
2703a2b906805985e0a4258bcbaed4cdff758875514Christian König{
271d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct vl_video_buffer *buffer;
272d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   struct pipe_resource templ;
2733a2b906805985e0a4258bcbaed4cdff758875514Christian König   unsigned i;
2743a2b906805985e0a4258bcbaed4cdff758875514Christian König
2754e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   assert(pipe);
276d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
277d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer = CALLOC_STRUCT(vl_video_buffer);
2783a2b906805985e0a4258bcbaed4cdff758875514Christian König
2794e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   buffer->base.context = pipe;
280d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer->base.destroy = vl_video_buffer_destroy;
2813ea7e2713c836f23d59c4034385609e371a94c8dChristian König   buffer->base.get_sampler_view_planes = vl_video_buffer_sampler_view_planes;
2823ea7e2713c836f23d59c4034385609e371a94c8dChristian König   buffer->base.get_sampler_view_components = vl_video_buffer_sampler_view_components;
283d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer->base.get_surfaces = vl_video_buffer_surfaces;
284559f6d6cf4a9469c2c6ccea482115f22080f185fChristian König   buffer->base.chroma_format = chroma_format;
285559f6d6cf4a9469c2c6ccea482115f22080f185fChristian König   buffer->base.width = width;
286559f6d6cf4a9469c2c6ccea482115f22080f185fChristian König   buffer->base.height = height;
2874f3fb1586aebfe248321e935651b5af92b5a8261Christian König   buffer->num_planes = 1;
288d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
289d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   memset(&templ, 0, sizeof(templ));
29031109e1be20d7c94521879c3221a9f77bacbdb8dChristian König   templ.target = depth > 1 ? PIPE_TEXTURE_3D : PIPE_TEXTURE_2D;
291d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   templ.format = resource_formats[0];
292d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   templ.width0 = width;
293d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   templ.height0 = height;
294d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   templ.depth0 = depth;
295d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   templ.array_size = 1;
296d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
297d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   templ.usage = usage;
298d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
299d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
300d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   if (!buffer->resources[0])
301d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      goto error;
302d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
3034f3fb1586aebfe248321e935651b5af92b5a8261Christian König   if (resource_formats[1] == PIPE_FORMAT_NONE) {
304d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      assert(chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444);
3054f3fb1586aebfe248321e935651b5af92b5a8261Christian König      assert(resource_formats[2] == PIPE_FORMAT_NONE);
306d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      return &buffer->base;
3074f3fb1586aebfe248321e935651b5af92b5a8261Christian König   } else
3084f3fb1586aebfe248321e935651b5af92b5a8261Christian König      buffer->num_planes = 2;
309d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
310d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   templ.format = resource_formats[1];
311d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
31231109e1be20d7c94521879c3221a9f77bacbdb8dChristian König      templ.width0 /= 2;
313d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      templ.height0 /= 2;
314d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   } else if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
31531109e1be20d7c94521879c3221a9f77bacbdb8dChristian König      templ.height0 /= 2;
3163a2b906805985e0a4258bcbaed4cdff758875514Christian König   }
317d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
318d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer->resources[1] = pipe->screen->resource_create(pipe->screen, &templ);
319d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   if (!buffer->resources[1])
320d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      goto error;
321d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
3224f3fb1586aebfe248321e935651b5af92b5a8261Christian König   if (resource_formats[2] == PIPE_FORMAT_NONE)
323d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      return &buffer->base;
3244f3fb1586aebfe248321e935651b5af92b5a8261Christian König   else
3254f3fb1586aebfe248321e935651b5af92b5a8261Christian König      buffer->num_planes = 3;
326d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
327d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   templ.format = resource_formats[2];
328d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   buffer->resources[2] = pipe->screen->resource_create(pipe->screen, &templ);
329d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   if (!buffer->resources[2])
330d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      goto error;
331d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
332d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return &buffer->base;
333d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
334d9ad3aa3b9647f1ede2568600978af956ff32fffChristian Königerror:
335d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   for (i = 0; i < VL_MAX_PLANES; ++i)
336d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      pipe_resource_reference(&buffer->resources[i], NULL);
337d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   FREE(buffer);
338d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
339d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   return NULL;
3403a2b906805985e0a4258bcbaed4cdff758875514Christian König}
341