vl_vertex_buffers.c revision d3770d6229d95e9beb67358ae2b2c8824ed3ae58
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 128struct pipe_vertex_buffer 129vl_vb_upload_block_num(struct pipe_context *pipe, unsigned num_blocks) 130{ 131 struct pipe_vertex_buffer buf; 132 struct pipe_transfer *buf_transfer; 133 struct vertex2s *v; 134 unsigned i; 135 136 assert(pipe); 137 138 /* create buffer */ 139 buf.stride = sizeof(struct vertex2s); 140 buf.buffer_offset = 0; 141 buf.buffer = pipe_buffer_create 142 ( 143 pipe->screen, 144 PIPE_BIND_VERTEX_BUFFER, 145 PIPE_USAGE_STATIC, 146 sizeof(struct vertex2s) * num_blocks 147 ); 148 149 if(!buf.buffer) 150 return buf; 151 152 /* and fill it */ 153 v = pipe_buffer_map 154 ( 155 pipe, 156 buf.buffer, 157 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 158 &buf_transfer 159 ); 160 161 for ( i = 0; i < num_blocks; ++i, ++v) { 162 v->x = i; 163 v->y = i; 164 } 165 166 pipe_buffer_unmap(pipe, buf_transfer); 167 168 return buf; 169} 170 171static struct pipe_vertex_element 172vl_vb_get_quad_vertex_element(void) 173{ 174 struct pipe_vertex_element element; 175 176 /* setup rectangle element */ 177 element.src_offset = 0; 178 element.instance_divisor = 0; 179 element.vertex_buffer_index = 0; 180 element.src_format = PIPE_FORMAT_R32G32_FLOAT; 181 182 return element; 183} 184 185static void 186vl_vb_element_helper(struct pipe_vertex_element* elements, unsigned num_elements, 187 unsigned vertex_buffer_index) 188{ 189 unsigned i, offset = 0; 190 191 assert(elements && num_elements); 192 193 for ( i = 0; i < num_elements; ++i ) { 194 elements[i].src_offset = offset; 195 elements[i].instance_divisor = 1; 196 elements[i].vertex_buffer_index = vertex_buffer_index; 197 offset += util_format_get_blocksize(elements[i].src_format); 198 } 199} 200 201void * 202vl_vb_get_ves_ycbcr(struct pipe_context *pipe) 203{ 204 struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS]; 205 206 assert(pipe); 207 208 memset(&vertex_elems, 0, sizeof(vertex_elems)); 209 vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element(); 210 211 /* Position element */ 212 vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R8G8B8A8_USCALED; 213 214 vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 1, 1); 215 216 /* block num element */ 217 vertex_elems[VS_I_BLOCK_NUM].src_format = PIPE_FORMAT_R16G16_SSCALED; 218 219 vl_vb_element_helper(&vertex_elems[VS_I_BLOCK_NUM], 1, 2); 220 221 return pipe->create_vertex_elements_state(pipe, 3, vertex_elems); 222} 223 224void * 225vl_vb_get_ves_mv(struct pipe_context *pipe) 226{ 227 struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS]; 228 229 assert(pipe); 230 231 memset(&vertex_elems, 0, sizeof(vertex_elems)); 232 vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element(); 233 234 /* Position element */ 235 vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R16G16_SSCALED; 236 237 vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 1, 1); 238 239 /* motion vector TOP element */ 240 vertex_elems[VS_I_MV_TOP].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED; 241 242 /* motion vector BOTTOM element */ 243 vertex_elems[VS_I_MV_BOTTOM].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED; 244 245 vl_vb_element_helper(&vertex_elems[VS_I_MV_TOP], 2, 2); 246 247 return pipe->create_vertex_elements_state(pipe, NUM_VS_INPUTS, vertex_elems); 248} 249 250bool 251vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe, 252 unsigned width, unsigned height) 253{ 254 unsigned i, size; 255 256 assert(buffer); 257 258 buffer->width = width; 259 buffer->height = height; 260 261 size = width * height; 262 263 for (i = 0; i < VL_MAX_PLANES; ++i) { 264 buffer->ycbcr[i].resource = pipe_buffer_create 265 ( 266 pipe->screen, 267 PIPE_BIND_VERTEX_BUFFER, 268 PIPE_USAGE_STREAM, 269 sizeof(struct vl_ycbcr_block) * size * 4 270 ); 271 if (!buffer->ycbcr[i].resource) 272 goto error_ycbcr; 273 } 274 275 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 276 buffer->mv[i].resource = pipe_buffer_create 277 ( 278 pipe->screen, 279 PIPE_BIND_VERTEX_BUFFER, 280 PIPE_USAGE_STREAM, 281 sizeof(struct vl_motionvector) * size 282 ); 283 if (!buffer->mv[i].resource) 284 goto error_mv; 285 } 286 287 vl_vb_map(buffer, pipe); 288 return true; 289 290error_mv: 291 for (i = 0; i < VL_MAX_PLANES; ++i) 292 pipe_resource_reference(&buffer->mv[i].resource, NULL); 293 294error_ycbcr: 295 for (i = 0; i < VL_MAX_PLANES; ++i) 296 pipe_resource_reference(&buffer->ycbcr[i].resource, NULL); 297 return false; 298} 299 300unsigned 301vl_vb_attributes_per_plock(struct vl_vertex_buffer *buffer) 302{ 303 return 1; 304} 305 306struct pipe_vertex_buffer 307vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer, int component) 308{ 309 struct pipe_vertex_buffer buf; 310 311 assert(buffer); 312 313 buf.stride = sizeof(struct vl_ycbcr_block); 314 buf.buffer_offset = 0; 315 buf.buffer = buffer->ycbcr[component].resource; 316 317 return buf; 318} 319 320struct pipe_vertex_buffer 321vl_vb_get_mv(struct vl_vertex_buffer *buffer, int motionvector) 322{ 323 struct pipe_vertex_buffer buf; 324 325 assert(buffer); 326 327 buf.stride = sizeof(struct vl_motionvector); 328 buf.buffer_offset = 0; 329 buf.buffer = buffer->mv[motionvector].resource; 330 331 return buf; 332} 333 334void 335vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe) 336{ 337 unsigned i; 338 339 assert(buffer && pipe); 340 341 for (i = 0; i < VL_MAX_PLANES; ++i) { 342 buffer->ycbcr[i].vertex_stream = pipe_buffer_map 343 ( 344 pipe, 345 buffer->ycbcr[i].resource, 346 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 347 &buffer->ycbcr[i].transfer 348 ); 349 } 350 351 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 352 buffer->mv[i].vertex_stream = pipe_buffer_map 353 ( 354 pipe, 355 buffer->mv[i].resource, 356 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 357 &buffer->mv[i].transfer 358 ); 359 } 360 361} 362 363struct vl_ycbcr_block * 364vl_vb_get_ycbcr_stream(struct vl_vertex_buffer *buffer, int component) 365{ 366 assert(buffer); 367 assert(component < VL_MAX_PLANES); 368 369 return buffer->ycbcr[component].vertex_stream; 370} 371 372unsigned 373vl_vb_get_mv_stream_stride(struct vl_vertex_buffer *buffer) 374{ 375 assert(buffer); 376 377 return buffer->width; 378} 379 380struct vl_motionvector * 381vl_vb_get_mv_stream(struct vl_vertex_buffer *buffer, int ref_frame) 382{ 383 assert(buffer); 384 assert(ref_frame < VL_MAX_REF_FRAMES); 385 386 return buffer->mv[ref_frame].vertex_stream; 387} 388 389void 390vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe) 391{ 392 unsigned i; 393 394 assert(buffer && pipe); 395 396 for (i = 0; i < VL_MAX_PLANES; ++i) { 397 pipe_buffer_unmap(pipe, buffer->ycbcr[i].transfer); 398 } 399 400 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 401 pipe_buffer_unmap(pipe, buffer->mv[i].transfer); 402 } 403} 404 405void 406vl_vb_cleanup(struct vl_vertex_buffer *buffer) 407{ 408 unsigned i; 409 410 assert(buffer); 411 412 for (i = 0; i < VL_MAX_PLANES; ++i) { 413 pipe_resource_reference(&buffer->ycbcr[i].resource, NULL); 414 } 415 416 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 417 pipe_resource_reference(&buffer->mv[i].resource, NULL); 418 } 419} 420