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