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