vl_vertex_buffers.c revision 24d76d2966a5c666c9627034e6751621b17024c8
1/************************************************************************** 2 * 3 * Copyright 2010 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#include <util/u_format.h> 30#include "vl_vertex_buffers.h" 31#include "vl_types.h" 32 33/* vertices for a quad covering a block */ 34static const struct vertex2f block_quad[4] = { 35 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} 36}; 37 38struct pipe_vertex_buffer 39vl_vb_upload_quads(struct pipe_context *pipe) 40{ 41 struct pipe_vertex_buffer quad; 42 struct pipe_transfer *buf_transfer; 43 struct vertex2f *v; 44 45 unsigned i; 46 47 assert(pipe); 48 49 /* create buffer */ 50 quad.stride = sizeof(struct vertex2f); 51 quad.buffer_offset = 0; 52 quad.buffer = pipe_buffer_create 53 ( 54 pipe->screen, 55 PIPE_BIND_VERTEX_BUFFER, 56 PIPE_USAGE_STATIC, 57 sizeof(struct vertex2f) * 4 58 ); 59 60 if(!quad.buffer) 61 return quad; 62 63 /* and fill it */ 64 v = pipe_buffer_map 65 ( 66 pipe, 67 quad.buffer, 68 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 69 &buf_transfer 70 ); 71 72 for (i = 0; i < 4; ++i, ++v) { 73 v->x = block_quad[i].x; 74 v->y = block_quad[i].y; 75 } 76 77 pipe_buffer_unmap(pipe, buf_transfer); 78 79 return quad; 80} 81 82struct pipe_vertex_buffer 83vl_vb_upload_pos(struct pipe_context *pipe, unsigned width, unsigned height) 84{ 85 struct pipe_vertex_buffer pos; 86 struct pipe_transfer *buf_transfer; 87 struct vertex2s *v; 88 89 unsigned x, y; 90 91 assert(pipe); 92 93 /* create buffer */ 94 pos.stride = sizeof(struct vertex2s); 95 pos.buffer_offset = 0; 96 pos.buffer = pipe_buffer_create 97 ( 98 pipe->screen, 99 PIPE_BIND_VERTEX_BUFFER, 100 PIPE_USAGE_STATIC, 101 sizeof(struct vertex2s) * width * height 102 ); 103 104 if(!pos.buffer) 105 return pos; 106 107 /* and fill it */ 108 v = pipe_buffer_map 109 ( 110 pipe, 111 pos.buffer, 112 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 113 &buf_transfer 114 ); 115 116 for ( y = 0; y < height; ++y) { 117 for ( x = 0; x < width; ++x, ++v) { 118 v->x = x; 119 v->y = y; 120 } 121 } 122 123 pipe_buffer_unmap(pipe, buf_transfer); 124 125 return pos; 126} 127 128static struct pipe_vertex_element 129vl_vb_get_quad_vertex_element(void) 130{ 131 struct pipe_vertex_element element; 132 133 /* setup rectangle element */ 134 element.src_offset = 0; 135 element.instance_divisor = 0; 136 element.vertex_buffer_index = 0; 137 element.src_format = PIPE_FORMAT_R32G32_FLOAT; 138 139 return element; 140} 141 142static void 143vl_vb_element_helper(struct pipe_vertex_element* elements, unsigned num_elements, 144 unsigned vertex_buffer_index) 145{ 146 unsigned i, offset = 0; 147 148 assert(elements && num_elements); 149 150 for ( i = 0; i < num_elements; ++i ) { 151 elements[i].src_offset = offset; 152 elements[i].instance_divisor = 1; 153 elements[i].vertex_buffer_index = vertex_buffer_index; 154 offset += util_format_get_blocksize(elements[i].src_format); 155 } 156} 157 158void * 159vl_vb_get_ves_ycbcr(struct pipe_context *pipe) 160{ 161 struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS]; 162 163 assert(pipe); 164 165 memset(&vertex_elems, 0, sizeof(vertex_elems)); 166 vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element(); 167 168 /* Position element */ 169 vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R8G8B8A8_USCALED; 170 171 vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 1, 1); 172 173 return pipe->create_vertex_elements_state(pipe, 2, vertex_elems); 174} 175 176void * 177vl_vb_get_ves_mv(struct pipe_context *pipe) 178{ 179 struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS]; 180 181 assert(pipe); 182 183 memset(&vertex_elems, 0, sizeof(vertex_elems)); 184 vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element(); 185 186 /* Position element */ 187 vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R16G16_SSCALED; 188 189 vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 1, 1); 190 191 /* motion vector TOP element */ 192 vertex_elems[VS_I_MV_TOP].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED; 193 194 /* motion vector BOTTOM element */ 195 vertex_elems[VS_I_MV_BOTTOM].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED; 196 197 vl_vb_element_helper(&vertex_elems[VS_I_MV_TOP], 2, 2); 198 199 return pipe->create_vertex_elements_state(pipe, NUM_VS_INPUTS, vertex_elems); 200} 201 202bool 203vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe, 204 unsigned width, unsigned height) 205{ 206 unsigned i, size; 207 208 assert(buffer); 209 210 buffer->width = width; 211 buffer->height = height; 212 213 size = width * height; 214 215 for (i = 0; i < VL_MAX_PLANES; ++i) { 216 buffer->ycbcr[i].resource = pipe_buffer_create 217 ( 218 pipe->screen, 219 PIPE_BIND_VERTEX_BUFFER, 220 PIPE_USAGE_STREAM, 221 sizeof(struct pipe_ycbcr_block) * size * 4 222 ); 223 if (!buffer->ycbcr[i].resource) 224 goto error_ycbcr; 225 } 226 227 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 228 buffer->mv[i].resource = pipe_buffer_create 229 ( 230 pipe->screen, 231 PIPE_BIND_VERTEX_BUFFER, 232 PIPE_USAGE_STREAM, 233 sizeof(struct pipe_motionvector) * size 234 ); 235 if (!buffer->mv[i].resource) 236 goto error_mv; 237 } 238 239 vl_vb_map(buffer, pipe); 240 return true; 241 242error_mv: 243 for (i = 0; i < VL_MAX_PLANES; ++i) 244 pipe_resource_reference(&buffer->mv[i].resource, NULL); 245 246error_ycbcr: 247 for (i = 0; i < VL_MAX_PLANES; ++i) 248 pipe_resource_reference(&buffer->ycbcr[i].resource, NULL); 249 return false; 250} 251 252struct pipe_vertex_buffer 253vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer, int component) 254{ 255 struct pipe_vertex_buffer buf; 256 257 assert(buffer); 258 259 buf.stride = sizeof(struct pipe_ycbcr_block); 260 buf.buffer_offset = 0; 261 buf.buffer = buffer->ycbcr[component].resource; 262 263 return buf; 264} 265 266struct pipe_vertex_buffer 267vl_vb_get_mv(struct vl_vertex_buffer *buffer, int motionvector) 268{ 269 struct pipe_vertex_buffer buf; 270 271 assert(buffer); 272 273 buf.stride = sizeof(struct pipe_motionvector); 274 buf.buffer_offset = 0; 275 buf.buffer = buffer->mv[motionvector].resource; 276 277 return buf; 278} 279 280void 281vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe) 282{ 283 unsigned i; 284 285 assert(buffer && pipe); 286 287 for (i = 0; i < VL_MAX_PLANES; ++i) { 288 buffer->ycbcr[i].vertex_stream = pipe_buffer_map 289 ( 290 pipe, 291 buffer->ycbcr[i].resource, 292 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 293 &buffer->ycbcr[i].transfer 294 ); 295 } 296 297 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 298 buffer->mv[i].vertex_stream = pipe_buffer_map 299 ( 300 pipe, 301 buffer->mv[i].resource, 302 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 303 &buffer->mv[i].transfer 304 ); 305 } 306 307} 308 309struct pipe_ycbcr_block * 310vl_vb_get_ycbcr_stream(struct vl_vertex_buffer *buffer, int component) 311{ 312 assert(buffer); 313 assert(component < VL_MAX_PLANES); 314 315 return buffer->ycbcr[component].vertex_stream; 316} 317 318unsigned 319vl_vb_get_mv_stream_stride(struct vl_vertex_buffer *buffer) 320{ 321 assert(buffer); 322 323 return buffer->width; 324} 325 326struct pipe_motionvector * 327vl_vb_get_mv_stream(struct vl_vertex_buffer *buffer, int ref_frame) 328{ 329 assert(buffer); 330 assert(ref_frame < VL_MAX_REF_FRAMES); 331 332 return buffer->mv[ref_frame].vertex_stream; 333} 334 335void 336vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe) 337{ 338 unsigned i; 339 340 assert(buffer && pipe); 341 342 for (i = 0; i < VL_MAX_PLANES; ++i) { 343 pipe_buffer_unmap(pipe, buffer->ycbcr[i].transfer); 344 } 345 346 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 347 pipe_buffer_unmap(pipe, buffer->mv[i].transfer); 348 } 349} 350 351void 352vl_vb_cleanup(struct vl_vertex_buffer *buffer) 353{ 354 unsigned i; 355 356 assert(buffer); 357 358 for (i = 0; i < VL_MAX_PLANES; ++i) { 359 pipe_resource_reference(&buffer->ycbcr[i].resource, NULL); 360 } 361 362 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 363 pipe_resource_reference(&buffer->mv[i].resource, NULL); 364 } 365} 366