vl_video_buffer.c revision 3ea7e2713c836f23d59c4034385609e371a94c8d
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 <assert.h> 29 30#include <pipe/p_screen.h> 31#include <pipe/p_context.h> 32#include <pipe/p_state.h> 33 34#include <util/u_format.h> 35#include <util/u_inlines.h> 36#include <util/u_sampler.h> 37#include <util/u_memory.h> 38 39#include "vl_video_buffer.h" 40 41static void 42vl_video_buffer_destroy(struct pipe_video_buffer *buffer) 43{ 44 struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer; 45 unsigned i; 46 47 assert(buf); 48 49 for (i = 0; i < VL_MAX_PLANES; ++i) { 50 pipe_surface_reference(&buf->surfaces[i], NULL); 51 pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL); 52 pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL); 53 pipe_resource_reference(&buf->resources[i], NULL); 54 } 55} 56 57static struct pipe_sampler_view ** 58vl_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer) 59{ 60 struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer; 61 struct pipe_sampler_view sv_templ; 62 struct pipe_context *pipe; 63 unsigned i; 64 65 assert(buf); 66 67 pipe = buf->pipe; 68 69 for (i = 0; i < buf->num_planes; ++i ) { 70 if (!buf->sampler_view_planes[i]) { 71 memset(&sv_templ, 0, sizeof(sv_templ)); 72 u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format); 73 74 if (util_format_get_nr_components(buf->resources[i]->format) == 1) 75 sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = sv_templ.swizzle_a = PIPE_SWIZZLE_RED; 76 77 buf->sampler_view_planes[i] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ); 78 if (!buf->sampler_view_planes[i]) 79 goto error; 80 } 81 } 82 83 return buf->sampler_view_planes; 84 85error: 86 for (i = 0; i < buf->num_planes; ++i ) 87 pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL); 88 89 return NULL; 90} 91 92static struct pipe_sampler_view ** 93vl_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer) 94{ 95 struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer; 96 struct pipe_sampler_view sv_templ; 97 struct pipe_context *pipe; 98 unsigned i, j, component; 99 100 assert(buf); 101 102 pipe = buf->pipe; 103 104 for (component = 0, i = 0; i < buf->num_planes; ++i ) { 105 unsigned nr_components = util_format_get_nr_components(buf->resources[i]->format); 106 107 for (j = 0; j < nr_components; ++j, ++component) { 108 assert(component < VL_MAX_PLANES); 109 110 if (!buf->sampler_view_components[component]) { 111 memset(&sv_templ, 0, sizeof(sv_templ)); 112 u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format); 113 sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j; 114 sv_templ.swizzle_a = PIPE_SWIZZLE_ONE; 115 buf->sampler_view_components[component] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ); 116 if (!buf->sampler_view_components[component]) 117 goto error; 118 } 119 } 120 } 121 122 return buf->sampler_view_components; 123 124error: 125 for (i = 0; i < VL_MAX_PLANES; ++i ) 126 pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL); 127 128 return NULL; 129} 130 131static struct pipe_surface ** 132vl_video_buffer_surfaces(struct pipe_video_buffer *buffer) 133{ 134 struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer; 135 struct pipe_surface surf_templ; 136 struct pipe_context *pipe; 137 unsigned i; 138 139 assert(buf); 140 141 pipe = buf->pipe; 142 143 for (i = 0; i < buf->num_planes; ++i ) { 144 if (!buf->surfaces[i]) { 145 memset(&surf_templ, 0, sizeof(surf_templ)); 146 surf_templ.format = buf->resources[i]->format; 147 surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 148 buf->surfaces[i] = pipe->create_surface(pipe, buf->resources[i], &surf_templ); 149 if (!buf->surfaces[i]) 150 goto error; 151 } 152 } 153 154 return buf->surfaces; 155 156error: 157 for (i = 0; i < buf->num_planes; ++i ) 158 pipe_surface_reference(&buf->surfaces[i], NULL); 159 160 return NULL; 161} 162 163struct pipe_video_buffer * 164vl_video_buffer_init(struct pipe_video_context *context, 165 struct pipe_context *pipe, 166 unsigned width, unsigned height, unsigned depth, 167 enum pipe_video_chroma_format chroma_format, 168 const enum pipe_format resource_formats[VL_MAX_PLANES], 169 unsigned usage) 170{ 171 struct vl_video_buffer *buffer; 172 struct pipe_resource templ; 173 unsigned i; 174 175 assert(context && pipe); 176 177 buffer = CALLOC_STRUCT(vl_video_buffer); 178 179 buffer->base.destroy = vl_video_buffer_destroy; 180 buffer->base.get_sampler_view_planes = vl_video_buffer_sampler_view_planes; 181 buffer->base.get_sampler_view_components = vl_video_buffer_sampler_view_components; 182 buffer->base.get_surfaces = vl_video_buffer_surfaces; 183 buffer->pipe = pipe; 184 buffer->num_planes = 1; 185 186 memset(&templ, 0, sizeof(templ)); 187 templ.target = depth > 1 ? PIPE_TEXTURE_3D : PIPE_TEXTURE_2D; 188 templ.format = resource_formats[0]; 189 templ.width0 = width; 190 templ.height0 = height; 191 templ.depth0 = depth; 192 templ.array_size = 1; 193 templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 194 templ.usage = usage; 195 196 buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ); 197 if (!buffer->resources[0]) 198 goto error; 199 200 if (resource_formats[1] == PIPE_FORMAT_NONE) { 201 assert(chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444); 202 assert(resource_formats[2] == PIPE_FORMAT_NONE); 203 return &buffer->base; 204 } else 205 buffer->num_planes = 2; 206 207 templ.format = resource_formats[1]; 208 if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { 209 templ.width0 /= 2; 210 templ.height0 /= 2; 211 } else if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { 212 templ.height0 /= 2; 213 } 214 215 buffer->resources[1] = pipe->screen->resource_create(pipe->screen, &templ); 216 if (!buffer->resources[1]) 217 goto error; 218 219 if (resource_formats[2] == PIPE_FORMAT_NONE) 220 return &buffer->base; 221 else 222 buffer->num_planes = 3; 223 224 templ.format = resource_formats[2]; 225 buffer->resources[2] = pipe->screen->resource_create(pipe->screen, &templ); 226 if (!buffer->resources[2]) 227 goto error; 228 229 return &buffer->base; 230 231error: 232 for (i = 0; i < VL_MAX_PLANES; ++i) 233 pipe_resource_reference(&buffer->resources[i], NULL); 234 FREE(buffer); 235 236 return NULL; 237} 238