Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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 */
  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.