vl_vertex_buffers.c revision 31096e13f858daf896c0c53077fb25e92da089a6
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 /* block num element */ 172 vertex_elems[VS_I_BLOCK_NUM].src_format = PIPE_FORMAT_R32_FLOAT; 173 174 vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 2, 1); 175 176 return pipe->create_vertex_elements_state(pipe, 3, vertex_elems); 177} 178 179void * 180vl_vb_get_ves_mv(struct pipe_context *pipe) 181{ 182 struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS]; 183 184 assert(pipe); 185 186 memset(&vertex_elems, 0, sizeof(vertex_elems)); 187 vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element(); 188 189 /* Position element */ 190 vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R16G16_SSCALED; 191 192 vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 1, 1); 193 194 /* motion vector TOP element */ 195 vertex_elems[VS_I_MV_TOP].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED; 196 197 /* motion vector BOTTOM element */ 198 vertex_elems[VS_I_MV_BOTTOM].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED; 199 200 vl_vb_element_helper(&vertex_elems[VS_I_MV_TOP], 2, 2); 201 202 return pipe->create_vertex_elements_state(pipe, NUM_VS_INPUTS, vertex_elems); 203} 204 205bool 206vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe, 207 unsigned width, unsigned height) 208{ 209 unsigned i, size; 210 211 assert(buffer); 212 213 buffer->width = width; 214 buffer->height = height; 215 216 size = width * height; 217 218 for (i = 0; i < VL_MAX_PLANES; ++i) { 219 buffer->ycbcr[i].resource = pipe_buffer_create 220 ( 221 pipe->screen, 222 PIPE_BIND_VERTEX_BUFFER, 223 PIPE_USAGE_STREAM, 224 sizeof(struct vl_ycbcr_block) * size * 4 225 ); 226 if (!buffer->ycbcr[i].resource) 227 goto error_ycbcr; 228 } 229 230 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 231 buffer->mv[i].resource = pipe_buffer_create 232 ( 233 pipe->screen, 234 PIPE_BIND_VERTEX_BUFFER, 235 PIPE_USAGE_STREAM, 236 sizeof(struct vl_motionvector) * size 237 ); 238 if (!buffer->mv[i].resource) 239 goto error_mv; 240 } 241 242 vl_vb_map(buffer, pipe); 243 return true; 244 245error_mv: 246 for (i = 0; i < VL_MAX_PLANES; ++i) 247 pipe_resource_reference(&buffer->mv[i].resource, NULL); 248 249error_ycbcr: 250 for (i = 0; i < VL_MAX_PLANES; ++i) 251 pipe_resource_reference(&buffer->ycbcr[i].resource, NULL); 252 return false; 253} 254 255unsigned 256vl_vb_attributes_per_plock(struct vl_vertex_buffer *buffer) 257{ 258 return 1; 259} 260 261struct pipe_vertex_buffer 262vl_vb_get_ycbcr(struct vl_vertex_buffer *buffer, int component) 263{ 264 struct pipe_vertex_buffer buf; 265 266 assert(buffer); 267 268 buf.stride = sizeof(struct vl_ycbcr_block); 269 buf.buffer_offset = 0; 270 buf.buffer = buffer->ycbcr[component].resource; 271 272 return buf; 273} 274 275struct pipe_vertex_buffer 276vl_vb_get_mv(struct vl_vertex_buffer *buffer, int motionvector) 277{ 278 struct pipe_vertex_buffer buf; 279 280 assert(buffer); 281 282 buf.stride = sizeof(struct vl_motionvector); 283 buf.buffer_offset = 0; 284 buf.buffer = buffer->mv[motionvector].resource; 285 286 return buf; 287} 288 289void 290vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe) 291{ 292 unsigned i; 293 294 assert(buffer && pipe); 295 296 for (i = 0; i < VL_MAX_PLANES; ++i) { 297 buffer->ycbcr[i].vertex_stream = pipe_buffer_map 298 ( 299 pipe, 300 buffer->ycbcr[i].resource, 301 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 302 &buffer->ycbcr[i].transfer 303 ); 304 } 305 306 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 307 buffer->mv[i].vertex_stream = pipe_buffer_map 308 ( 309 pipe, 310 buffer->mv[i].resource, 311 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 312 &buffer->mv[i].transfer 313 ); 314 } 315 316} 317 318struct vl_ycbcr_block * 319vl_vb_get_ycbcr_stream(struct vl_vertex_buffer *buffer, int component) 320{ 321 assert(buffer); 322 assert(component < VL_MAX_PLANES); 323 324 return buffer->ycbcr[component].vertex_stream; 325} 326 327unsigned 328vl_vb_get_mv_stream_stride(struct vl_vertex_buffer *buffer) 329{ 330 assert(buffer); 331 332 return buffer->width; 333} 334 335struct vl_motionvector * 336vl_vb_get_mv_stream(struct vl_vertex_buffer *buffer, int ref_frame) 337{ 338 assert(buffer); 339 assert(ref_frame < VL_MAX_REF_FRAMES); 340 341 return buffer->mv[ref_frame].vertex_stream; 342} 343 344void 345vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe) 346{ 347 unsigned i; 348 349 assert(buffer && pipe); 350 351 for (i = 0; i < VL_MAX_PLANES; ++i) { 352 pipe_buffer_unmap(pipe, buffer->ycbcr[i].transfer); 353 } 354 355 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 356 pipe_buffer_unmap(pipe, buffer->mv[i].transfer); 357 } 358} 359 360void 361vl_vb_cleanup(struct vl_vertex_buffer *buffer) 362{ 363 unsigned i; 364 365 assert(buffer); 366 367 for (i = 0; i < VL_MAX_PLANES; ++i) { 368 pipe_resource_reference(&buffer->ycbcr[i].resource, NULL); 369 } 370 371 for (i = 0; i < VL_MAX_REF_FRAMES; ++i) { 372 pipe_resource_reference(&buffer->mv[i].resource, NULL); 373 } 374} 375