1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2011 Christian König.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <assert.h>
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_state.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_sampler.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vl_video_buffer.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst enum pipe_format const_resource_formats_YV12[3] = {
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_R8_UNORM,
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_R8_UNORM,
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_R8_UNORM
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst enum pipe_format const_resource_formats_NV12[3] = {
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_R8_UNORM,
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_R8G8_UNORM,
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_NONE
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst enum pipe_format const_resource_formats_YUVA[3] = {
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_R8G8B8A8_UNORM,
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_NONE,
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_NONE
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst enum pipe_format const_resource_formats_VUYA[3] = {
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_B8G8R8A8_UNORM,
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_NONE,
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_NONE
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst enum pipe_format const_resource_formats_YUYV[3] = {
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_R8G8_R8B8_UNORM,
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_NONE,
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_NONE
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst enum pipe_format const_resource_formats_UYVY[3] = {
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_G8R8_B8R8_UNORM,
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_NONE,
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PIPE_FORMAT_NONE
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst unsigned const_resource_plane_order_YUV[3] = {
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   0,
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   1,
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   2
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst unsigned const_resource_plane_order_YVU[3] = {
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   0,
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   2,
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   1
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst enum pipe_format *
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_formats(struct pipe_screen *screen, enum pipe_format format)
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(format) {
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_YV12:
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return const_resource_formats_YV12;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_NV12:
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return const_resource_formats_NV12;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_R8G8B8A8_UNORM:
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return const_resource_formats_YUVA;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_B8G8R8A8_UNORM:
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return const_resource_formats_VUYA;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_YUYV:
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return const_resource_formats_YUYV;
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_UYVY:
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return const_resource_formats_UYVY;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst unsigned *
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_plane_order(enum pipe_format format)
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch(format) {
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_YV12:
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return const_resource_plane_order_YVU;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_NV12:
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_R8G8B8A8_UNORM:
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_B8G8R8A8_UNORM:
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_YUYV:
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_FORMAT_UYVY:
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return const_resource_plane_order_YUV;
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum pipe_format
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_surface_format(enum pipe_format format)
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct util_format_description *desc = util_format_description(format);
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* a subsampled formats can't work as surface use RGBA instead */
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED)
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return PIPE_FORMAT_R8G8B8A8_UNORM;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return format;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_is_format_supported(struct pipe_screen *screen,
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    enum pipe_format format,
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    enum pipe_video_profile profile)
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const enum pipe_format *resource_formats;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   resource_formats = vl_video_buffer_formats(screen, format);
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!resource_formats)
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      enum pipe_format format = resource_formats[i];
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (format == PIPE_FORMAT_NONE)
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         continue;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* we at least need to sample from it */
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW))
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return false;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      format = vl_video_buffer_surface_format(format);
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET))
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return false;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_max_size(struct pipe_screen *screen)
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t max_2d_texture_level;
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   max_2d_texture_level = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return 1 << (max_2d_texture_level-1);
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_set_associated_data(struct pipe_video_buffer *vbuf,
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    struct pipe_video_decoder *vdec,
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    void *associated_data,
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    void (*destroy_associated_data)(void *))
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vbuf->decoder = vdec;
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (vbuf->associated_data == associated_data)
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (vbuf->associated_data)
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vbuf->destroy_associated_data(vbuf->associated_data);
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vbuf->associated_data = associated_data;
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vbuf->destroy_associated_data = destroy_associated_data;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid *
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_get_associated_data(struct pipe_video_buffer *vbuf,
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    struct pipe_video_decoder *vdec)
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (vbuf->decoder == vdec)
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return vbuf->associated_data;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_vide_buffer_template(struct pipe_resource *templ,
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct pipe_video_buffer *tmpl,
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        enum pipe_format resource_format,
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        unsigned depth, unsigned usage, unsigned plane)
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(templ, 0, sizeof(*templ));
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templ->target = depth > 1 ? PIPE_TEXTURE_3D : PIPE_TEXTURE_2D;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templ->format = resource_format;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templ->width0 = tmpl->width;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templ->height0 = tmpl->height;
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templ->depth0 = depth;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templ->array_size = 1;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templ->bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templ->usage = usage;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (plane > 0) {
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (tmpl->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         templ->width0 /= 2;
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         templ->height0 /= 2;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (tmpl->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         templ->height0 /= 2;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_destroy(struct pipe_video_buffer *buffer)
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(buf);
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_resource_reference(&buf->resources[i], NULL);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < VL_NUM_COMPONENTS * 2; ++i)
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_surface_reference(&buf->surfaces[i], NULL);
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vl_video_buffer_set_associated_data(buffer, NULL, NULL, NULL);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(buffer);
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_sampler_view **
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_sampler_view sv_templ;
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_context *pipe;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(buf);
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe = buf->base.context;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < buf->num_planes; ++i ) {
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!buf->sampler_view_planes[i]) {
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         memset(&sv_templ, 0, sizeof(sv_templ));
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format);
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (util_format_get_nr_components(buf->resources[i]->format) == 1)
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = sv_templ.swizzle_a = PIPE_SWIZZLE_RED;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         buf->sampler_view_planes[i] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ);
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!buf->sampler_view_planes[i])
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            goto error;
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return buf->sampler_view_planes;
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgerror:
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < buf->num_planes; ++i )
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_sampler_view **
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_sampler_view sv_templ;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_context *pipe;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const enum pipe_format *sampler_format;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned *plane_order;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i, j, component;
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(buf);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe = buf->base.context;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sampler_format = vl_video_buffer_formats(pipe->screen, buf->base.buffer_format);
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   plane_order = vl_video_buffer_plane_order(buf->base.buffer_format);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (component = 0, i = 0; i < buf->num_planes; ++i ) {
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct pipe_resource *res = buf->resources[plane_order[i]];
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const struct util_format_description *desc = util_format_description(res->format);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned nr_components = util_format_get_nr_components(res->format);
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED)
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nr_components = 3;
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j = 0; j < nr_components && component < VL_NUM_COMPONENTS; ++j, ++component) {
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (buf->sampler_view_components[component])
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            continue;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         memset(&sv_templ, 0, sizeof(sv_templ));
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         u_sampler_view_default_template(&sv_templ, res, sampler_format[plane_order[i]]);
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         buf->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!buf->sampler_view_components[component])
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            goto error;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(component == VL_NUM_COMPONENTS);
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return buf->sampler_view_components;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgerror:
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < VL_NUM_COMPONENTS; ++i )
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_surface **
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_surfaces(struct pipe_video_buffer *buffer)
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_surface surf_templ;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_context *pipe;
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i, j, depth, surf;
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(buf);
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe = buf->base.context;
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   depth = buffer->interlaced ? 2 : 1;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0, surf = 0; i < depth; ++i ) {
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (j = 0; j < VL_NUM_COMPONENTS; ++j, ++surf) {
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(surf < (VL_NUM_COMPONENTS * 2));
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!buf->resources[j]) {
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            pipe_surface_reference(&buf->surfaces[surf], NULL);
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            continue;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!buf->surfaces[surf]) {
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            memset(&surf_templ, 0, sizeof(surf_templ));
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            surf_templ.format = vl_video_buffer_surface_format(buf->resources[j]->format);
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = i;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            buf->surfaces[surf] = pipe->create_surface(pipe, buf->resources[j], &surf_templ);
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!buf->surfaces[surf])
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               goto error;
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return buf->surfaces;
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgerror:
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < (VL_NUM_COMPONENTS * 2); ++i )
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_surface_reference(&buf->surfaces[i], NULL);
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_video_buffer *
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_create(struct pipe_context *pipe,
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const struct pipe_video_buffer *tmpl)
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const enum pipe_format *resource_formats;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_video_buffer templat, *result;
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool pot_buffers;
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(pipe);
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(tmpl->width > 0 && tmpl->height > 0);
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pot_buffers = !pipe->screen->get_video_param
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe->screen,
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PIPE_VIDEO_PROFILE_UNKNOWN,
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PIPE_VIDEO_CAP_NPOT_TEXTURES
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   );
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   resource_formats = vl_video_buffer_formats(pipe->screen, tmpl->buffer_format);
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!resource_formats)
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templat = *tmpl;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templat.width = pot_buffers ? util_next_power_of_two(tmpl->width)
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 : align(tmpl->width, VL_MACROBLOCK_WIDTH);
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   templat.height = pot_buffers ? util_next_power_of_two(tmpl->height)
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  : align(tmpl->height, VL_MACROBLOCK_HEIGHT);
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (tmpl->interlaced)
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      templat.height /= 2;
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   result = vl_video_buffer_create_ex
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe, &templat, resource_formats,
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tmpl->interlaced ? 2 : 1, PIPE_USAGE_STATIC
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   );
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (result && tmpl->interlaced)
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result->height *= 2;
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return result;
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_video_buffer *
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_create_ex(struct pipe_context *pipe,
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          const struct pipe_video_buffer *tmpl,
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          const enum pipe_format resource_formats[VL_NUM_COMPONENTS],
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          unsigned depth, unsigned usage)
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_resource res_tmpl;
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_resource *resources[VL_NUM_COMPONENTS];
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(pipe);
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(resources, 0, sizeof resources);
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[0], depth, usage, 0);
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   resources[0] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!resources[0])
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error;
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (resource_formats[1] == PIPE_FORMAT_NONE) {
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(resource_formats[2] == PIPE_FORMAT_NONE);
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return vl_video_buffer_create_ex2(pipe, tmpl, resources);
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[1], depth, usage, 1);
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   resources[1] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!resources[1])
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error;
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (resource_formats[2] == PIPE_FORMAT_NONE)
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return vl_video_buffer_create_ex2(pipe, tmpl, resources);
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[2], depth, usage, 2);
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   resources[2] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!resources[2])
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      goto error;
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return vl_video_buffer_create_ex2(pipe, tmpl, resources);
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgerror:
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < VL_NUM_COMPONENTS; ++i)
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe_resource_reference(&resources[i], NULL);
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_video_buffer *
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvl_video_buffer_create_ex2(struct pipe_context *pipe,
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           const struct pipe_video_buffer *tmpl,
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct pipe_resource *resources[VL_NUM_COMPONENTS])
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vl_video_buffer *buffer;
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer = CALLOC_STRUCT(vl_video_buffer);
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->base = *tmpl;
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->base.context = pipe;
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->base.destroy = vl_video_buffer_destroy;
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->base.get_sampler_view_planes = vl_video_buffer_sampler_view_planes;
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->base.get_sampler_view_components = vl_video_buffer_sampler_view_components;
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->base.get_surfaces = vl_video_buffer_surfaces;
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   buffer->num_planes = 0;
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      buffer->resources[i] = resources[i];
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (resources[i])
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         buffer->num_planes++;
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &buffer->base;
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
505