Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. #include "xorg_exa.h"
  2. #include "xorg_renderer.h"
  3.  
  4. #include "xorg_exa_tgsi.h"
  5.  
  6. #include "cso_cache/cso_context.h"
  7. #include "util/u_draw_quad.h"
  8. #include "util/u_math.h"
  9. #include "util/u_memory.h"
  10. #include "util/u_sampler.h"
  11.  
  12. #include "util/u_inlines.h"
  13. #include "util/u_box.h"
  14.  
  15. #include <math.h>
  16.  
  17. #define floatsEqual(x, y) (fabs(x - y) <= 0.00001f * MIN2(fabs(x), fabs(y)))
  18. #define floatIsZero(x) (floatsEqual((x) + 1, 1))
  19.  
  20. #define NUM_COMPONENTS 4
  21.  
  22. static INLINE boolean is_affine(float *matrix)
  23. {
  24.    return floatIsZero(matrix[2]) && floatIsZero(matrix[5])
  25.       && floatsEqual(matrix[8], 1);
  26. }
  27. static INLINE void map_point(float *mat, float x, float y,
  28.                              float *out_x, float *out_y)
  29. {
  30.    if (!mat) {
  31.       *out_x = x;
  32.       *out_y = y;
  33.       return;
  34.    }
  35.  
  36.    *out_x = mat[0]*x + mat[3]*y + mat[6];
  37.    *out_y = mat[1]*x + mat[4]*y + mat[7];
  38.    if (!is_affine(mat)) {
  39.       float w = 1/(mat[2]*x + mat[5]*y + mat[8]);
  40.       *out_x *= w;
  41.       *out_y *= w;
  42.    }
  43. }
  44.  
  45. static INLINE void
  46. renderer_draw(struct xorg_renderer *r)
  47. {
  48.    int num_verts = r->buffer_size/(r->attrs_per_vertex * NUM_COMPONENTS);
  49.  
  50.    if (!r->buffer_size)
  51.       return;
  52.  
  53.    cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
  54.    util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
  55.                                 num_verts, r->attrs_per_vertex);
  56.  
  57.    r->buffer_size = 0;
  58. }
  59.  
  60. static INLINE void
  61. renderer_draw_conditional(struct xorg_renderer *r,
  62.                           int next_batch)
  63. {
  64.    if (r->buffer_size + next_batch >= BUF_SIZE ||
  65.        (next_batch == 0 && r->buffer_size)) {
  66.       renderer_draw(r);
  67.    }
  68. }
  69.  
  70. static void
  71. renderer_init_state(struct xorg_renderer *r)
  72. {
  73.    struct pipe_depth_stencil_alpha_state dsa;
  74.    struct pipe_rasterizer_state raster;
  75.    unsigned i;
  76.  
  77.    /* set common initial clip state */
  78.    memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
  79.    cso_set_depth_stencil_alpha(r->cso, &dsa);
  80.  
  81.  
  82.    /* XXX: move to renderer_init_state? */
  83.    memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
  84.    raster.half_pixel_center = 1;
  85.    raster.bottom_edge_rule = 1;
  86.    raster.depth_clip = 1;
  87.    cso_set_rasterizer(r->cso, &raster);
  88.  
  89.    /* vertex elements state */
  90.    memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3);
  91.    for (i = 0; i < 3; i++) {
  92.       r->velems[i].src_offset = i * 4 * sizeof(float);
  93.       r->velems[i].instance_divisor = 0;
  94.       r->velems[i].vertex_buffer_index = 0;
  95.       r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  96.    }
  97. }
  98.  
  99.  
  100. static INLINE void
  101. add_vertex_color(struct xorg_renderer *r,
  102.                  float x, float y,
  103.                  float color[4])
  104. {
  105.    float *vertex = r->buffer + r->buffer_size;
  106.  
  107.    vertex[0] = x;
  108.    vertex[1] = y;
  109.    vertex[2] = 0.f; /*z*/
  110.    vertex[3] = 1.f; /*w*/
  111.  
  112.    vertex[4] = color[0]; /*r*/
  113.    vertex[5] = color[1]; /*g*/
  114.    vertex[6] = color[2]; /*b*/
  115.    vertex[7] = color[3]; /*a*/
  116.  
  117.    r->buffer_size += 8;
  118. }
  119.  
  120. static INLINE void
  121. add_vertex_1tex(struct xorg_renderer *r,
  122.                 float x, float y, float s, float t)
  123. {
  124.    float *vertex = r->buffer + r->buffer_size;
  125.  
  126.    vertex[0] = x;
  127.    vertex[1] = y;
  128.    vertex[2] = 0.f; /*z*/
  129.    vertex[3] = 1.f; /*w*/
  130.  
  131.    vertex[4] = s;   /*s*/
  132.    vertex[5] = t;   /*t*/
  133.    vertex[6] = 0.f; /*r*/
  134.    vertex[7] = 1.f; /*q*/
  135.  
  136.    r->buffer_size += 8;
  137. }
  138.  
  139. static void
  140. add_vertex_data1(struct xorg_renderer *r,
  141.                  float srcX, float srcY,  float dstX, float dstY,
  142.                  float width, float height,
  143.                  struct pipe_resource *src, float *src_matrix)
  144. {
  145.    float s0, t0, s1, t1, s2, t2, s3, t3;
  146.    float pt0[2], pt1[2], pt2[2], pt3[2];
  147.  
  148.    pt0[0] = srcX;
  149.    pt0[1] = srcY;
  150.    pt1[0] = (srcX + width);
  151.    pt1[1] = srcY;
  152.    pt2[0] = (srcX + width);
  153.    pt2[1] = (srcY + height);
  154.    pt3[0] = srcX;
  155.    pt3[1] = (srcY + height);
  156.  
  157.    if (src_matrix) {
  158.       map_point(src_matrix, pt0[0], pt0[1], &pt0[0], &pt0[1]);
  159.       map_point(src_matrix, pt1[0], pt1[1], &pt1[0], &pt1[1]);
  160.       map_point(src_matrix, pt2[0], pt2[1], &pt2[0], &pt2[1]);
  161.       map_point(src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]);
  162.    }
  163.  
  164.    s0 =  pt0[0] / src->width0;
  165.    s1 =  pt1[0] / src->width0;
  166.    s2 =  pt2[0] / src->width0;
  167.    s3 =  pt3[0] / src->width0;
  168.    t0 =  pt0[1] / src->height0;
  169.    t1 =  pt1[1] / src->height0;
  170.    t2 =  pt2[1] / src->height0;
  171.    t3 =  pt3[1] / src->height0;
  172.  
  173.    /* 1st vertex */
  174.    add_vertex_1tex(r, dstX, dstY, s0, t0);
  175.    /* 2nd vertex */
  176.    add_vertex_1tex(r, dstX + width, dstY, s1, t1);
  177.    /* 3rd vertex */
  178.    add_vertex_1tex(r, dstX + width, dstY + height, s2, t2);
  179.    /* 4th vertex */
  180.    add_vertex_1tex(r, dstX, dstY + height, s3, t3);
  181. }
  182.  
  183.  
  184. static INLINE void
  185. add_vertex_2tex(struct xorg_renderer *r,
  186.                 float x, float y,
  187.                 float s0, float t0, float s1, float t1)
  188. {
  189.    float *vertex = r->buffer + r->buffer_size;
  190.  
  191.    vertex[0] = x;
  192.    vertex[1] = y;
  193.    vertex[2] = 0.f; /*z*/
  194.    vertex[3] = 1.f; /*w*/
  195.  
  196.    vertex[4] = s0;  /*s*/
  197.    vertex[5] = t0;  /*t*/
  198.    vertex[6] = 0.f; /*r*/
  199.    vertex[7] = 1.f; /*q*/
  200.  
  201.    vertex[8] = s1;  /*s*/
  202.    vertex[9] = t1;  /*t*/
  203.    vertex[10] = 0.f; /*r*/
  204.    vertex[11] = 1.f; /*q*/
  205.  
  206.    r->buffer_size += 12;
  207. }
  208.  
  209. static void
  210. add_vertex_data2(struct xorg_renderer *r,
  211.                  float srcX, float srcY, float maskX, float maskY,
  212.                  float dstX, float dstY, float width, float height,
  213.                  struct pipe_resource *src,
  214.                  struct pipe_resource *mask,
  215.                  float *src_matrix, float *mask_matrix)
  216. {
  217.    float src_s0, src_t0, src_s1, src_t1, src_s2, src_t2, src_s3, src_t3;
  218.    float mask_s0, mask_t0, mask_s1, mask_t1, mask_s2, mask_t2, mask_s3, mask_t3;
  219.    float spt0[2], spt1[2], spt2[2], spt3[2];
  220.    float mpt0[2], mpt1[2], mpt2[2], mpt3[2];
  221.  
  222.    spt0[0] = srcX;
  223.    spt0[1] = srcY;
  224.    spt1[0] = (srcX + width);
  225.    spt1[1] = srcY;
  226.    spt2[0] = (srcX + width);
  227.    spt2[1] = (srcY + height);
  228.    spt3[0] = srcX;
  229.    spt3[1] = (srcY + height);
  230.  
  231.    mpt0[0] = maskX;
  232.    mpt0[1] = maskY;
  233.    mpt1[0] = (maskX + width);
  234.    mpt1[1] = maskY;
  235.    mpt2[0] = (maskX + width);
  236.    mpt2[1] = (maskY + height);
  237.    mpt3[0] = maskX;
  238.    mpt3[1] = (maskY + height);
  239.  
  240.    if (src_matrix) {
  241.       map_point(src_matrix, spt0[0], spt0[1], &spt0[0], &spt0[1]);
  242.       map_point(src_matrix, spt1[0], spt1[1], &spt1[0], &spt1[1]);
  243.       map_point(src_matrix, spt2[0], spt2[1], &spt2[0], &spt2[1]);
  244.       map_point(src_matrix, spt3[0], spt3[1], &spt3[0], &spt3[1]);
  245.    }
  246.  
  247.    if (mask_matrix) {
  248.       map_point(mask_matrix, mpt0[0], mpt0[1], &mpt0[0], &mpt0[1]);
  249.       map_point(mask_matrix, mpt1[0], mpt1[1], &mpt1[0], &mpt1[1]);
  250.       map_point(mask_matrix, mpt2[0], mpt2[1], &mpt2[0], &mpt2[1]);
  251.       map_point(mask_matrix, mpt3[0], mpt3[1], &mpt3[0], &mpt3[1]);
  252.    }
  253.  
  254.    src_s0 =  spt0[0] / src->width0;
  255.    src_s1 =  spt1[0] / src->width0;
  256.    src_s2 =  spt2[0] / src->width0;
  257.    src_s3 =  spt3[0] / src->width0;
  258.    src_t0 =  spt0[1] / src->height0;
  259.    src_t1 =  spt1[1] / src->height0;
  260.    src_t2 =  spt2[1] / src->height0;
  261.    src_t3 =  spt3[1] / src->height0;
  262.  
  263.    mask_s0 =  mpt0[0] / mask->width0;
  264.    mask_s1 =  mpt1[0] / mask->width0;
  265.    mask_s2 =  mpt2[0] / mask->width0;
  266.    mask_s3 =  mpt3[0] / mask->width0;
  267.    mask_t0 =  mpt0[1] / mask->height0;
  268.    mask_t1 =  mpt1[1] / mask->height0;
  269.    mask_t2 =  mpt2[1] / mask->height0;
  270.    mask_t3 =  mpt3[1] / mask->height0;
  271.  
  272.    /* 1st vertex */
  273.    add_vertex_2tex(r, dstX, dstY,
  274.                    src_s0, src_t0, mask_s0, mask_t0);
  275.    /* 2nd vertex */
  276.    add_vertex_2tex(r, dstX + width, dstY,
  277.                    src_s1, src_t1, mask_s1, mask_t1);
  278.    /* 3rd vertex */
  279.    add_vertex_2tex(r, dstX + width, dstY + height,
  280.                    src_s2, src_t2, mask_s2, mask_t2);
  281.    /* 4th vertex */
  282.    add_vertex_2tex(r, dstX, dstY + height,
  283.                    src_s3, src_t3, mask_s3, mask_t3);
  284. }
  285.  
  286. static void
  287. setup_vertex_data_yuv(struct xorg_renderer *r,
  288.                       float srcX, float srcY, float srcW, float srcH,
  289.                       float dstX, float dstY, float dstW, float dstH,
  290.                       struct pipe_resource **tex)
  291. {
  292.    float s0, t0, s1, t1;
  293.    float spt0[2], spt1[2];
  294.  
  295.    spt0[0] = srcX;
  296.    spt0[1] = srcY;
  297.    spt1[0] = srcX + srcW;
  298.    spt1[1] = srcY + srcH;
  299.  
  300.    s0 = spt0[0] / tex[0]->width0;
  301.    t0 = spt0[1] / tex[0]->height0;
  302.    s1 = spt1[0] / tex[0]->width0;
  303.    t1 = spt1[1] / tex[0]->height0;
  304.  
  305.    /* 1st vertex */
  306.    add_vertex_1tex(r, dstX, dstY, s0, t0);
  307.    /* 2nd vertex */
  308.    add_vertex_1tex(r, dstX + dstW, dstY,
  309.                    s1, t0);
  310.    /* 3rd vertex */
  311.    add_vertex_1tex(r, dstX + dstW, dstY + dstH,
  312.                    s1, t1);
  313.    /* 4th vertex */
  314.    add_vertex_1tex(r, dstX, dstY + dstH,
  315.                    s0, t1);
  316. }
  317.  
  318.  
  319.  
  320. /* Set up framebuffer, viewport and vertex shader constant buffer
  321.  * state for a particular destinaton surface.  In all our rendering,
  322.  * these concepts are linked.
  323.  */
  324. void renderer_bind_destination(struct xorg_renderer *r,
  325.                                struct pipe_surface *surface,
  326.                                int width,
  327.                                int height )
  328. {
  329.  
  330.    struct pipe_framebuffer_state fb;
  331.    struct pipe_viewport_state viewport;
  332.  
  333.    /* Framebuffer uses actual surface width/height
  334.     */
  335.    memset(&fb, 0, sizeof fb);
  336.    fb.width  = surface->width;
  337.    fb.height = surface->height;
  338.    fb.nr_cbufs = 1;
  339.    fb.cbufs[0] = surface;
  340.    fb.zsbuf = 0;
  341.  
  342.    /* Viewport just touches the bit we're interested in:
  343.     */
  344.    viewport.scale[0] =  width / 2.f;
  345.    viewport.scale[1] =  height / 2.f;
  346.    viewport.scale[2] =  1.0;
  347.    viewport.scale[3] =  1.0;
  348.    viewport.translate[0] = width / 2.f;
  349.    viewport.translate[1] = height / 2.f;
  350.    viewport.translate[2] = 0.0;
  351.    viewport.translate[3] = 0.0;
  352.  
  353.    /* Constant buffer set up to match viewport dimensions:
  354.     */
  355.    if (r->fb_width != width ||
  356.        r->fb_height != height)
  357.    {
  358.       float vs_consts[8] = {
  359.          2.f/width, 2.f/height, 1, 1,
  360.          -1, -1, 0, 0
  361.       };
  362.  
  363.       r->fb_width = width;
  364.       r->fb_height = height;
  365.  
  366.       renderer_set_constants(r, PIPE_SHADER_VERTEX,
  367.                              vs_consts, sizeof vs_consts);
  368.    }
  369.  
  370.    cso_set_framebuffer(r->cso, &fb);
  371.    cso_set_viewport(r->cso, &viewport);
  372. }
  373.  
  374.  
  375. struct xorg_renderer * renderer_create(struct pipe_context *pipe)
  376. {
  377.    struct xorg_renderer *renderer = CALLOC_STRUCT(xorg_renderer);
  378.  
  379.    renderer->pipe = pipe;
  380.    renderer->cso = cso_create_context(pipe);
  381.    renderer->shaders = xorg_shaders_create(renderer);
  382.  
  383.    renderer_init_state(renderer);
  384.  
  385.    return renderer;
  386. }
  387.  
  388. void renderer_destroy(struct xorg_renderer *r)
  389. {
  390.    struct pipe_resource **vsbuf = &r->vs_const_buffer;
  391.    struct pipe_resource **fsbuf = &r->fs_const_buffer;
  392.  
  393.    if (*vsbuf)
  394.       pipe_resource_reference(vsbuf, NULL);
  395.  
  396.    if (*fsbuf)
  397.       pipe_resource_reference(fsbuf, NULL);
  398.  
  399.    if (r->shaders) {
  400.       xorg_shaders_destroy(r->shaders);
  401.       r->shaders = NULL;
  402.    }
  403.  
  404.    if (r->cso) {
  405.       cso_release_all(r->cso);
  406.       cso_destroy_context(r->cso);
  407.       r->cso = NULL;
  408.    }
  409. }
  410.  
  411.  
  412.  
  413.  
  414.  
  415. void renderer_set_constants(struct xorg_renderer *r,
  416.                             int shader_type,
  417.                             const float *params,
  418.                             int param_bytes)
  419. {
  420.    struct pipe_resource **cbuf =
  421.       (shader_type == PIPE_SHADER_VERTEX) ? &r->vs_const_buffer :
  422.       &r->fs_const_buffer;
  423.  
  424.    pipe_resource_reference(cbuf, NULL);
  425.    *cbuf = pipe_buffer_create(r->pipe->screen,
  426.                               PIPE_BIND_CONSTANT_BUFFER,
  427.                               PIPE_USAGE_STATIC,
  428.                               param_bytes);
  429.  
  430.    if (*cbuf) {
  431.       pipe_buffer_write(r->pipe, *cbuf,
  432.                         0, param_bytes, params);
  433.    }
  434.    pipe_set_constant_buffer(r->pipe, shader_type, 0, *cbuf);
  435. }
  436.  
  437.  
  438.  
  439. void renderer_draw_yuv(struct xorg_renderer *r,
  440.                        float src_x, float src_y, float src_w, float src_h,
  441.                        int dst_x, int dst_y, int dst_w, int dst_h,
  442.                        struct pipe_resource **textures)
  443. {
  444.    const int num_attribs = 2; /*pos + tex coord*/
  445.  
  446.    setup_vertex_data_yuv(r,
  447.                          src_x, src_y, src_w, src_h,
  448.                          dst_x, dst_y, dst_w, dst_h,
  449.                          textures);
  450.  
  451.    cso_set_vertex_elements(r->cso, num_attribs, r->velems);
  452.  
  453.    util_draw_user_vertex_buffer(r->cso, r->buffer,
  454.                                 PIPE_PRIM_QUADS,
  455.                                 4,  /* verts */
  456.                                 num_attribs); /* attribs/vert */
  457.  
  458.    r->buffer_size = 0;
  459. }
  460.  
  461. void renderer_begin_solid(struct xorg_renderer *r)
  462. {
  463.    r->buffer_size = 0;
  464.    r->attrs_per_vertex = 2;
  465. }
  466.  
  467. void renderer_solid(struct xorg_renderer *r,
  468.                     int x0, int y0,
  469.                     int x1, int y1,
  470.                     float *color)
  471. {
  472.    /*
  473.    debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
  474.    x0, y0, x1, y1, color[0], color[1], color[2], color[3]);*/
  475.  
  476.    renderer_draw_conditional(r, 4 * 8);
  477.  
  478.    /* 1st vertex */
  479.    add_vertex_color(r, x0, y0, color);
  480.    /* 2nd vertex */
  481.    add_vertex_color(r, x1, y0, color);
  482.    /* 3rd vertex */
  483.    add_vertex_color(r, x1, y1, color);
  484.    /* 4th vertex */
  485.    add_vertex_color(r, x0, y1, color);
  486. }
  487.  
  488. void renderer_draw_flush(struct xorg_renderer *r)
  489. {
  490.    renderer_draw_conditional(r, 0);
  491. }
  492.  
  493. void renderer_begin_textures(struct xorg_renderer *r,
  494.                              int num_textures)
  495. {
  496.    r->attrs_per_vertex = 1 + num_textures;
  497.    r->buffer_size = 0;
  498. }
  499.  
  500. void renderer_texture(struct xorg_renderer *r,
  501.                       int *pos,
  502.                       int width, int height,
  503.                       struct pipe_sampler_view **sampler_view,
  504.                       int num_textures,
  505.                       float *src_matrix,
  506.                       float *mask_matrix)
  507. {
  508.  
  509. #if 0
  510.    if (src_matrix) {
  511.       debug_printf("src_matrix = \n");
  512.       debug_printf("%f, %f, %f\n", src_matrix[0], src_matrix[1], src_matrix[2]);
  513.       debug_printf("%f, %f, %f\n", src_matrix[3], src_matrix[4], src_matrix[5]);
  514.       debug_printf("%f, %f, %f\n", src_matrix[6], src_matrix[7], src_matrix[8]);
  515.    }
  516.    if (mask_matrix) {
  517.       debug_printf("mask_matrix = \n");
  518.       debug_printf("%f, %f, %f\n", mask_matrix[0], mask_matrix[1], mask_matrix[2]);
  519.       debug_printf("%f, %f, %f\n", mask_matrix[3], mask_matrix[4], mask_matrix[5]);
  520.       debug_printf("%f, %f, %f\n", mask_matrix[6], mask_matrix[7], mask_matrix[8]);
  521.    }
  522. #endif
  523.  
  524.    switch(r->attrs_per_vertex) {
  525.    case 2:
  526.       renderer_draw_conditional(r, 4 * 8);
  527.       add_vertex_data1(r,
  528.                        pos[0], pos[1], /* src */
  529.                        pos[4], pos[5], /* dst */
  530.                        width, height,
  531.                        sampler_view[0]->texture, src_matrix);
  532.       break;
  533.    case 3:
  534.       renderer_draw_conditional(r, 4 * 12);
  535.       add_vertex_data2(r,
  536.                        pos[0], pos[1], /* src */
  537.                        pos[2], pos[3], /* mask */
  538.                        pos[4], pos[5], /* dst */
  539.                        width, height,
  540.                        sampler_view[0]->texture, sampler_view[1]->texture,
  541.                        src_matrix, mask_matrix);
  542.       break;
  543.    default:
  544.       debug_assert(!"Unsupported number of textures");
  545.       break;
  546.    }
  547. }
  548.