[g3dvl] rename ycbcr buffer to video buffer and add some more functionality
[mesa.git] / src / gallium / auxiliary / vl / vl_video_buffer.c
1 /**************************************************************************
2 *
3 * Copyright 2011 Christian König.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "vl_video_buffer.h"
29 #include <util/u_format.h>
30 #include <util/u_inlines.h>
31 #include <util/u_sampler.h>
32 #include <pipe/p_screen.h>
33 #include <pipe/p_context.h>
34 #include <assert.h>
35
36 bool vl_video_buffer_init(struct vl_video_buffer *buffer,
37 struct pipe_context *pipe,
38 unsigned width, unsigned height, unsigned depth,
39 enum pipe_video_chroma_format chroma_format,
40 unsigned num_planes,
41 const enum pipe_format resource_format[VL_MAX_PLANES],
42 unsigned usage)
43 {
44 struct pipe_resource templ;
45 unsigned i;
46
47 assert(buffer && pipe);
48 assert(num_planes > 0 && num_planes <= VL_MAX_PLANES);
49
50 memset(buffer, 0, sizeof(struct vl_video_buffer));
51 buffer->pipe = pipe;
52 buffer->num_planes = num_planes;
53
54 memset(&templ, 0, sizeof(templ));
55 templ.target = PIPE_TEXTURE_2D;
56 templ.format = resource_format[0];
57 templ.width0 = width;
58 templ.height0 = height;
59 templ.depth0 = depth;
60 templ.array_size = 1;
61 templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
62 templ.usage = usage;
63
64 buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
65 if (!buffer->resources[0])
66 goto error;
67
68 if (num_planes == 1) {
69 assert(chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444);
70 return true;
71 }
72
73 templ.format = resource_format[1];
74 if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
75 if (depth > 1)
76 templ.depth0 /= 2;
77 else
78 templ.width0 /= 2;
79 templ.height0 /= 2;
80 } else if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
81 if (depth > 1)
82 templ.depth0 /= 2;
83 else
84 templ.height0 /= 2;
85 }
86
87 buffer->resources[1] = pipe->screen->resource_create(pipe->screen, &templ);
88 if (!buffer->resources[1])
89 goto error;
90
91 if (num_planes == 2)
92 return true;
93
94 templ.format = resource_format[2];
95 buffer->resources[2] = pipe->screen->resource_create(pipe->screen, &templ);
96 if (!buffer->resources[2])
97 goto error;
98
99 return true;
100
101 error:
102 for (i = 0; i < VL_MAX_PLANES; ++i)
103 pipe_resource_reference(&buffer->resources[i], NULL);
104
105 return false;
106 }
107
108 static inline void
109 adjust_swizzle(struct pipe_sampler_view *sv_templ)
110 {
111 if (util_format_get_nr_components(sv_templ->format) == 1) {
112 sv_templ->swizzle_r = PIPE_SWIZZLE_RED;
113 sv_templ->swizzle_g = PIPE_SWIZZLE_RED;
114 sv_templ->swizzle_b = PIPE_SWIZZLE_RED;
115 sv_templ->swizzle_a = PIPE_SWIZZLE_RED;
116 }
117 }
118
119 vl_sampler_views *vl_video_buffer_sampler_views(struct vl_video_buffer *buffer)
120 {
121 struct pipe_sampler_view sv_templ;
122 struct pipe_context *pipe;
123 unsigned i;
124
125 assert(buffer);
126
127 pipe = buffer->pipe;
128
129 for (i = 0; i < buffer->num_planes; ++i ) {
130 if (!buffer->sampler_views[i]) {
131 memset(&sv_templ, 0, sizeof(sv_templ));
132 u_sampler_view_default_template(&sv_templ, buffer->resources[i], buffer->resources[i]->format);
133 adjust_swizzle(&sv_templ);
134 buffer->sampler_views[i] = pipe->create_sampler_view(pipe, buffer->resources[i], &sv_templ);
135 if (!buffer->sampler_views[i])
136 goto error;
137 }
138 }
139
140 return &buffer->sampler_views;
141
142 error:
143 for (i = 0; i < buffer->num_planes; ++i )
144 pipe_sampler_view_reference(&buffer->sampler_views[i], NULL);
145
146 return NULL;
147 }
148
149 vl_surfaces *vl_video_buffer_surfaces(struct vl_video_buffer *buffer)
150 {
151 struct pipe_surface surf_templ;
152 struct pipe_context *pipe;
153 unsigned i;
154
155 assert(buffer);
156
157 pipe = buffer->pipe;
158
159 for (i = 0; i < buffer->num_planes; ++i ) {
160 if (!buffer->surfaces[i]) {
161 memset(&surf_templ, 0, sizeof(surf_templ));
162 surf_templ.format = buffer->resources[i]->format;
163 surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
164 buffer->surfaces[i] = pipe->create_surface(pipe, buffer->resources[i], &surf_templ);
165 if (!buffer->surfaces[i])
166 goto error;
167 }
168 }
169
170 return &buffer->surfaces;
171
172 error:
173 for (i = 0; i < buffer->num_planes; ++i )
174 pipe_surface_reference(&buffer->surfaces[i], NULL);
175
176 return NULL;
177 }
178
179 void vl_video_buffer_cleanup(struct vl_video_buffer *buffer)
180 {
181 unsigned i;
182
183 assert(buffer);
184
185 for (i = 0; i < VL_MAX_PLANES; ++i) {
186 pipe_surface_reference(&buffer->surfaces[i], NULL);
187 pipe_sampler_view_reference(&buffer->sampler_views[i], NULL);
188 pipe_resource_reference(&buffer->resources[i], NULL);
189 }
190 }