Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2009 VMware, Inc.  All Rights Reserved.
  4.  * Copyright 2010 LunarG, Inc.  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 VMWARE 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 "renderer.h"
  29.  
  30. #include "vg_context.h"
  31.  
  32. #include "pipe/p_context.h"
  33. #include "pipe/p_state.h"
  34. #include "util/u_inlines.h"
  35. #include "pipe/p_screen.h"
  36. #include "pipe/p_shader_tokens.h"
  37.  
  38. #include "util/u_draw_quad.h"
  39. #include "util/u_simple_shaders.h"
  40. #include "util/u_memory.h"
  41. #include "util/u_sampler.h"
  42. #include "util/u_surface.h"
  43. #include "util/u_math.h"
  44. #include "util/u_format.h"
  45.  
  46. #include "cso_cache/cso_context.h"
  47. #include "tgsi/tgsi_ureg.h"
  48.  
  49. typedef enum {
  50.    RENDERER_STATE_INIT,
  51.    RENDERER_STATE_COPY,
  52.    RENDERER_STATE_DRAWTEX,
  53.    RENDERER_STATE_SCISSOR,
  54.    RENDERER_STATE_CLEAR,
  55.    RENDERER_STATE_FILTER,
  56.    RENDERER_STATE_POLYGON_STENCIL,
  57.    RENDERER_STATE_POLYGON_FILL,
  58.    NUM_RENDERER_STATES
  59. } RendererState;
  60.  
  61. typedef enum {
  62.    RENDERER_VS_PLAIN,
  63.    RENDERER_VS_COLOR,
  64.    RENDERER_VS_TEXTURE,
  65.    NUM_RENDERER_VS
  66. } RendererVs;
  67.  
  68. typedef enum {
  69.    RENDERER_FS_COLOR,
  70.    RENDERER_FS_TEXTURE,
  71.    RENDERER_FS_SCISSOR,
  72.    RENDERER_FS_WHITE,
  73.    NUM_RENDERER_FS
  74. } RendererFs;
  75.  
  76. struct renderer {
  77.    struct pipe_context *pipe;
  78.    struct cso_context *cso;
  79.  
  80.    VGbitfield dirty;
  81.    struct {
  82.       struct pipe_rasterizer_state rasterizer;
  83.       struct pipe_depth_stencil_alpha_state dsa;
  84.       struct pipe_framebuffer_state fb;
  85.    } g3d;
  86.    struct matrix projection;
  87.  
  88.    struct matrix mvp;
  89.    struct pipe_resource *vs_cbuf;
  90.  
  91.    struct pipe_resource *fs_cbuf;
  92.    VGfloat fs_cbuf_data[32];
  93.    VGint fs_cbuf_len;
  94.  
  95.    struct pipe_vertex_element velems[2];
  96.    VGfloat vertices[4][2][4];
  97.  
  98.    void *cached_vs[NUM_RENDERER_VS];
  99.    void *cached_fs[NUM_RENDERER_FS];
  100.  
  101.    RendererState state;
  102.  
  103.    /* state data */
  104.    union {
  105.       struct {
  106.          VGint tex_width;
  107.          VGint tex_height;
  108.       } copy;
  109.  
  110.       struct {
  111.          VGint tex_width;
  112.          VGint tex_height;
  113.       } drawtex;
  114.  
  115.       struct {
  116.          VGboolean restore_dsa;
  117.       } scissor;
  118.  
  119.       struct {
  120.          VGboolean use_sampler;
  121.          VGint tex_width, tex_height;
  122.       } filter;
  123.  
  124.       struct {
  125.          struct pipe_depth_stencil_alpha_state dsa;
  126.          VGboolean manual_two_sides;
  127.          VGboolean restore_dsa;
  128.       } polygon_stencil;
  129.    } u;
  130. };
  131.  
  132. /**
  133.  * Return VG_TRUE if the renderer can use the resource as the asked bindings.
  134.  */
  135. static VGboolean renderer_can_support(struct renderer *renderer,
  136.                                       struct pipe_resource *res,
  137.                                       unsigned bindings)
  138. {
  139.    struct pipe_screen *screen = renderer->pipe->screen;
  140.  
  141.    return screen->is_format_supported(screen,
  142.          res->format, res->target, 0, bindings);
  143. }
  144.  
  145. /**
  146.  * Set the model-view-projection matrix used by vertex shaders.
  147.  */
  148. static void renderer_set_mvp(struct renderer *renderer,
  149.                              const struct matrix *mvp)
  150. {
  151.    struct matrix *cur = &renderer->mvp;
  152.    struct pipe_resource *cbuf;
  153.    VGfloat consts[3][4];
  154.    VGint i;
  155.  
  156.    /* projection only */
  157.    if (!mvp)
  158.       mvp = &renderer->projection;
  159.  
  160.    /* re-upload only if necessary */
  161.    if (memcmp(cur, mvp, sizeof(*mvp)) == 0)
  162.       return;
  163.  
  164.    /* 3x3 matrix to 3 constant vectors (no Z) */
  165.    for (i = 0; i < 3; i++) {
  166.       consts[i][0] = mvp->m[i + 0];
  167.       consts[i][1] = mvp->m[i + 3];
  168.       consts[i][2] = 0.0f;
  169.       consts[i][3] = mvp->m[i + 6];
  170.    }
  171.  
  172.    cbuf = renderer->vs_cbuf;
  173.    pipe_resource_reference(&cbuf, NULL);
  174.    cbuf = pipe_buffer_create(renderer->pipe->screen,
  175.                              PIPE_BIND_CONSTANT_BUFFER,
  176.                              PIPE_USAGE_STATIC,
  177.                              sizeof(consts));
  178.    if (cbuf) {
  179.       pipe_buffer_write(renderer->pipe, cbuf,
  180.             0, sizeof(consts), consts);
  181.    }
  182.    pipe_set_constant_buffer(renderer->pipe,
  183.          PIPE_SHADER_VERTEX, 0, cbuf);
  184.  
  185.    memcpy(cur, mvp, sizeof(*mvp));
  186.    renderer->vs_cbuf = cbuf;
  187. }
  188.  
  189. /**
  190.  * Create a simple vertex shader that passes through position and the given
  191.  * attribute.
  192.  */
  193. static void *create_passthrough_vs(struct pipe_context *pipe, int semantic_name)
  194. {
  195.    struct ureg_program *ureg;
  196.    struct ureg_src src[2], constants[3];
  197.    struct ureg_dst dst[2], tmp;
  198.    int i;
  199.  
  200.    ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
  201.    if (!ureg)
  202.       return NULL;
  203.  
  204.    /* position is in user coordinates */
  205.    src[0] = ureg_DECL_vs_input(ureg, 0);
  206.    dst[0] = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
  207.    tmp = ureg_DECL_temporary(ureg);
  208.    for (i = 0; i < Elements(constants); i++)
  209.       constants[i] = ureg_DECL_constant(ureg, i);
  210.  
  211.    /* transform to clipped coordinates */
  212.    ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), src[0], constants[0]);
  213.    ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Y), src[0], constants[1]);
  214.    ureg_MOV(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Z), src[0]);
  215.    ureg_DP4(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_W), src[0], constants[2]);
  216.    ureg_MOV(ureg, dst[0], ureg_src(tmp));
  217.  
  218.    if (semantic_name >= 0) {
  219.       src[1] = ureg_DECL_vs_input(ureg, 1);
  220.       dst[1] = ureg_DECL_output(ureg, semantic_name, 0);
  221.       ureg_MOV(ureg, dst[1], src[1]);
  222.    }
  223.  
  224.    ureg_END(ureg);
  225.  
  226.    return ureg_create_shader_and_destroy(ureg, pipe);
  227. }
  228.  
  229. /**
  230.  * Set renderer vertex shader.
  231.  *
  232.  * This function modifies vertex_shader state.
  233.  */
  234. static void renderer_set_vs(struct renderer *r, RendererVs id)
  235. {
  236.    /* create as needed */
  237.    if (!r->cached_vs[id]) {
  238.       int semantic_name = -1;
  239.  
  240.       switch (id) {
  241.       case RENDERER_VS_PLAIN:
  242.          break;
  243.       case RENDERER_VS_COLOR:
  244.          semantic_name = TGSI_SEMANTIC_COLOR;
  245.          break;
  246.       case RENDERER_VS_TEXTURE:
  247.          semantic_name = TGSI_SEMANTIC_GENERIC;
  248.          break;
  249.       default:
  250.          assert(!"Unknown renderer vs id");
  251.          break;
  252.       }
  253.  
  254.       r->cached_vs[id] = create_passthrough_vs(r->pipe, semantic_name);
  255.    }
  256.  
  257.    cso_set_vertex_shader_handle(r->cso, r->cached_vs[id]);
  258. }
  259.  
  260. /**
  261.  * Create a simple fragment shader that sets the depth to 0.0f.
  262.  */
  263. static void *create_scissor_fs(struct pipe_context *pipe)
  264. {
  265.    struct ureg_program *ureg;
  266.    struct ureg_dst out;
  267.    struct ureg_src imm;
  268.  
  269.    ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
  270.    out = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
  271.    imm = ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 0.0f);
  272.  
  273.    ureg_MOV(ureg, ureg_writemask(out, TGSI_WRITEMASK_Z), imm);
  274.    ureg_END(ureg);
  275.  
  276.    return ureg_create_shader_and_destroy(ureg, pipe);
  277. }
  278.  
  279. /**
  280.  * Create a simple fragment shader that sets the color to white.
  281.  */
  282. static void *create_white_fs(struct pipe_context *pipe)
  283. {
  284.    struct ureg_program *ureg;
  285.    struct ureg_dst out;
  286.    struct ureg_src imm;
  287.  
  288.    ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
  289.    out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
  290.    imm = ureg_imm4f(ureg, 1.0f, 1.0f, 1.0f, 1.0f);
  291.  
  292.    ureg_MOV(ureg, out, imm);
  293.    ureg_END(ureg);
  294.  
  295.    return ureg_create_shader_and_destroy(ureg, pipe);
  296. }
  297.  
  298. /**
  299.  * Set renderer fragment shader.
  300.  *
  301.  * This function modifies fragment_shader state.
  302.  */
  303. static void renderer_set_fs(struct renderer *r, RendererFs id)
  304. {
  305.    /* create as needed */
  306.    if (!r->cached_fs[id]) {
  307.       void *fs = NULL;
  308.  
  309.       switch (id) {
  310.       case RENDERER_FS_COLOR:
  311.          fs = util_make_fragment_passthrough_shader(r->pipe,
  312.                           TGSI_SEMANTIC_COLOR, TGSI_INTERPOLATE_PERSPECTIVE,
  313.                           TRUE);
  314.          break;
  315.       case RENDERER_FS_TEXTURE:
  316.          fs = util_make_fragment_tex_shader(r->pipe,
  317.                TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR);
  318.          break;
  319.       case RENDERER_FS_SCISSOR:
  320.          fs = create_scissor_fs(r->pipe);
  321.          break;
  322.       case RENDERER_FS_WHITE:
  323.          fs = create_white_fs(r->pipe);
  324.          break;
  325.       default:
  326.          assert(!"Unknown renderer fs id");
  327.          break;
  328.       }
  329.  
  330.       r->cached_fs[id] = fs;
  331.    }
  332.  
  333.    cso_set_fragment_shader_handle(r->cso, r->cached_fs[id]);
  334. }
  335.  
  336. typedef enum {
  337.    VEGA_Y0_TOP,
  338.    VEGA_Y0_BOTTOM
  339. } VegaOrientation;
  340.  
  341. static void vg_set_viewport(struct renderer *r,
  342.                             VegaOrientation orientation)
  343. {
  344.    const struct pipe_framebuffer_state *fb = &r->g3d.fb;
  345.    struct pipe_viewport_state viewport;
  346.    VGfloat y_scale = (orientation == VEGA_Y0_BOTTOM) ? -2.f : 2.f;
  347.  
  348.    viewport.scale[0] =  fb->width / 2.f;
  349.    viewport.scale[1] =  fb->height / y_scale;
  350.    viewport.scale[2] =  1.0;
  351.    viewport.scale[3] =  1.0;
  352.    viewport.translate[0] = fb->width / 2.f;
  353.    viewport.translate[1] = fb->height / 2.f;
  354.    viewport.translate[2] = 0.0;
  355.    viewport.translate[3] = 0.0;
  356.  
  357.    cso_set_viewport(r->cso, &viewport);
  358. }
  359.  
  360. /**
  361.  * Set renderer target.
  362.  *
  363.  * This function modifies framebuffer and viewport states.
  364.  */
  365. static void renderer_set_target(struct renderer *r,
  366.                                 struct pipe_surface *cbuf,
  367.                                 struct pipe_surface *zsbuf,
  368.                                 VGboolean y0_top)
  369. {
  370.    struct pipe_framebuffer_state fb;
  371.  
  372.    memset(&fb, 0, sizeof(fb));
  373.    fb.width = cbuf->width;
  374.    fb.height = cbuf->height;
  375.    fb.cbufs[0] = cbuf;
  376.    fb.nr_cbufs = 1;
  377.    fb.zsbuf = zsbuf;
  378.    cso_set_framebuffer(r->cso, &fb);
  379.  
  380.    vg_set_viewport(r, (y0_top) ? VEGA_Y0_TOP : VEGA_Y0_BOTTOM);
  381. }
  382.  
  383. /**
  384.  * Set renderer blend state.  Blending is disabled.
  385.  *
  386.  * This function modifies blend state.
  387.  */
  388. static void renderer_set_blend(struct renderer *r,
  389.                                VGbitfield channel_mask)
  390. {
  391.    struct pipe_blend_state blend;
  392.  
  393.    memset(&blend, 0, sizeof(blend));
  394.  
  395.    blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
  396.    blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
  397.    blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
  398.    blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
  399.  
  400.    if (channel_mask & VG_RED)
  401.       blend.rt[0].colormask |= PIPE_MASK_R;
  402.    if (channel_mask & VG_GREEN)
  403.       blend.rt[0].colormask |= PIPE_MASK_G;
  404.    if (channel_mask & VG_BLUE)
  405.       blend.rt[0].colormask |= PIPE_MASK_B;
  406.    if (channel_mask & VG_ALPHA)
  407.       blend.rt[0].colormask |= PIPE_MASK_A;
  408.  
  409.    cso_set_blend(r->cso, &blend);
  410. }
  411.  
  412. /**
  413.  * Set renderer sampler and view states.
  414.  *
  415.  * This function modifies samplers and fragment_sampler_views states.
  416.  */
  417. static void renderer_set_samplers(struct renderer *r,
  418.                                   uint num_views,
  419.                                   struct pipe_sampler_view **views)
  420. {
  421.    struct pipe_sampler_state sampler;
  422.    unsigned tex_filter = PIPE_TEX_FILTER_NEAREST;
  423.    unsigned tex_wrap = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  424.    uint i;
  425.  
  426.    memset(&sampler, 0, sizeof(sampler));
  427.  
  428.    sampler.min_img_filter = tex_filter;
  429.    sampler.mag_img_filter = tex_filter;
  430.    sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
  431.  
  432.    sampler.wrap_s = tex_wrap;
  433.    sampler.wrap_t = tex_wrap;
  434.    sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  435.  
  436.    sampler.normalized_coords = 1;
  437.  
  438.    /* set samplers */
  439.    for (i = 0; i < num_views; i++)
  440.       cso_single_sampler(r->cso, PIPE_SHADER_FRAGMENT, i, &sampler);
  441.    cso_single_sampler_done(r->cso, PIPE_SHADER_FRAGMENT);
  442.  
  443.    /* set views */
  444.    cso_set_sampler_views(r->cso, PIPE_SHADER_FRAGMENT, num_views, views);
  445. }
  446.  
  447. /**
  448.  * Set custom renderer fragment shader, and optionally set samplers and views
  449.  * and upload the fragment constant buffer.
  450.  *
  451.  * This function modifies fragment_shader, samplers and fragment_sampler_views
  452.  * states.
  453.  */
  454. static void renderer_set_custom_fs(struct renderer *renderer,
  455.                                    void *fs,
  456.                                    const struct pipe_sampler_state **samplers,
  457.                                    struct pipe_sampler_view **views,
  458.                                    VGint num_samplers,
  459.                                    const void *const_buffer,
  460.                                    VGint const_buffer_len)
  461. {
  462.    cso_set_fragment_shader_handle(renderer->cso, fs);
  463.  
  464.    /* set samplers and views */
  465.    if (num_samplers) {
  466.       cso_set_samplers(renderer->cso, PIPE_SHADER_FRAGMENT, num_samplers, samplers);
  467.       cso_set_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT, num_samplers, views);
  468.    }
  469.  
  470.    /* upload fs constant buffer */
  471.    if (const_buffer_len) {
  472.       struct pipe_resource *cbuf = renderer->fs_cbuf;
  473.  
  474.       if (!cbuf || renderer->fs_cbuf_len != const_buffer_len ||
  475.           memcmp(renderer->fs_cbuf_data, const_buffer, const_buffer_len)) {
  476.          pipe_resource_reference(&cbuf, NULL);
  477.  
  478.          cbuf = pipe_buffer_create(renderer->pipe->screen,
  479.                PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STATIC,
  480.                const_buffer_len);
  481.          pipe_buffer_write(renderer->pipe, cbuf, 0,
  482.                const_buffer_len, const_buffer);
  483.          pipe_set_constant_buffer(renderer->pipe,
  484.                PIPE_SHADER_FRAGMENT, 0, cbuf);
  485.  
  486.          renderer->fs_cbuf = cbuf;
  487.          if (const_buffer_len <= sizeof(renderer->fs_cbuf_data)) {
  488.             memcpy(renderer->fs_cbuf_data, const_buffer, const_buffer_len);
  489.             renderer->fs_cbuf_len = const_buffer_len;
  490.          }
  491.          else {
  492.             renderer->fs_cbuf_len = 0;
  493.          }
  494.       }
  495.    }
  496. }
  497.  
  498. /**
  499.  * Setup renderer quad position.
  500.  */
  501. static void renderer_quad_pos(struct renderer *r,
  502.                               VGfloat x0, VGfloat y0,
  503.                               VGfloat x1, VGfloat y1,
  504.                               VGboolean scissor)
  505. {
  506.    VGfloat z;
  507.  
  508.    /* the depth test is used for scissoring */
  509.    z = (scissor) ? 0.0f : 1.0f;
  510.  
  511.    /* positions */
  512.    r->vertices[0][0][0] = x0;
  513.    r->vertices[0][0][1] = y0;
  514.    r->vertices[0][0][2] = z;
  515.  
  516.    r->vertices[1][0][0] = x1;
  517.    r->vertices[1][0][1] = y0;
  518.    r->vertices[1][0][2] = z;
  519.  
  520.    r->vertices[2][0][0] = x1;
  521.    r->vertices[2][0][1] = y1;
  522.    r->vertices[2][0][2] = z;
  523.  
  524.    r->vertices[3][0][0] = x0;
  525.    r->vertices[3][0][1] = y1;
  526.    r->vertices[3][0][2] = z;
  527. }
  528.  
  529. /**
  530.  * Setup renderer quad texture coordinates.
  531.  */
  532. static void renderer_quad_texcoord(struct renderer *r,
  533.                                    VGfloat x0, VGfloat y0,
  534.                                    VGfloat x1, VGfloat y1,
  535.                                    VGint tex_width, VGint tex_height)
  536. {
  537.    VGfloat s0, t0, s1, t1, r0, q0;
  538.    VGint i;
  539.  
  540.    s0 = x0 / tex_width;
  541.    s1 = x1 / tex_width;
  542.    t0 = y0 / tex_height;
  543.    t1 = y1 / tex_height;
  544.    r0 = 0.0f;
  545.    q0 = 1.0f;
  546.  
  547.    /* texcoords */
  548.    r->vertices[0][1][0] = s0;
  549.    r->vertices[0][1][1] = t0;
  550.  
  551.    r->vertices[1][1][0] = s1;
  552.    r->vertices[1][1][1] = t0;
  553.  
  554.    r->vertices[2][1][0] = s1;
  555.    r->vertices[2][1][1] = t1;
  556.  
  557.    r->vertices[3][1][0] = s0;
  558.    r->vertices[3][1][1] = t1;
  559.  
  560.    for (i = 0; i < 4; i++) {
  561.       r->vertices[i][1][2] = r0;
  562.       r->vertices[i][1][3] = q0;
  563.    }
  564. }
  565.  
  566. /**
  567.  * Draw renderer quad.
  568.  */
  569. static void renderer_quad_draw(struct renderer *r)
  570. {
  571.    util_draw_user_vertex_buffer(r->cso, r->vertices, PIPE_PRIM_TRIANGLE_FAN,
  572.                                 Elements(r->vertices),     /* verts */
  573.                                 Elements(r->vertices[0])); /* attribs/vert */
  574. }
  575.  
  576. /**
  577.  * Prepare the renderer for copying.
  578.  */
  579. VGboolean renderer_copy_begin(struct renderer *renderer,
  580.                               struct pipe_surface *dst,
  581.                               VGboolean y0_top,
  582.                               struct pipe_sampler_view *src)
  583. {
  584.    assert(renderer->state == RENDERER_STATE_INIT);
  585.  
  586.    /* sanity check */
  587.    if (!renderer_can_support(renderer,
  588.             dst->texture, PIPE_BIND_RENDER_TARGET) ||
  589.        !renderer_can_support(renderer,
  590.           src->texture, PIPE_BIND_SAMPLER_VIEW))
  591.       return VG_FALSE;
  592.  
  593.    cso_save_framebuffer(renderer->cso);
  594.    cso_save_viewport(renderer->cso);
  595.    cso_save_blend(renderer->cso);
  596.    cso_save_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
  597.    cso_save_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
  598.    cso_save_fragment_shader(renderer->cso);
  599.    cso_save_vertex_shader(renderer->cso);
  600.  
  601.    renderer_set_target(renderer, dst, NULL, y0_top);
  602.  
  603.    renderer_set_blend(renderer, ~0);
  604.    renderer_set_samplers(renderer, 1, &src);
  605.  
  606.    renderer_set_fs(renderer, RENDERER_FS_TEXTURE);
  607.    renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
  608.  
  609.    renderer_set_mvp(renderer, NULL);
  610.  
  611.    /* remember the texture size */
  612.    renderer->u.copy.tex_width = src->texture->width0;
  613.    renderer->u.copy.tex_height = src->texture->height0;
  614.    renderer->state = RENDERER_STATE_COPY;
  615.  
  616.    return VG_TRUE;
  617. }
  618.  
  619. /**
  620.  * Draw into the destination rectangle given by (x, y, w, h).  The texture is
  621.  * sampled from within the rectangle given by (sx, sy, sw, sh).
  622.  *
  623.  * The coordinates are in surface coordinates.
  624.  */
  625. void renderer_copy(struct renderer *renderer,
  626.                    VGint x, VGint y, VGint w, VGint h,
  627.                    VGint sx, VGint sy, VGint sw, VGint sh)
  628. {
  629.    assert(renderer->state == RENDERER_STATE_COPY);
  630.  
  631.    /* there is no depth buffer for scissoring anyway */
  632.    renderer_quad_pos(renderer, x, y, x + w, y + h, VG_FALSE);
  633.    renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
  634.          renderer->u.copy.tex_width,
  635.          renderer->u.copy.tex_height);
  636.  
  637.    renderer_quad_draw(renderer);
  638. }
  639.  
  640. /**
  641.  * End copying and restore the states.
  642.  */
  643. void renderer_copy_end(struct renderer *renderer)
  644. {
  645.    assert(renderer->state == RENDERER_STATE_COPY);
  646.  
  647.    cso_restore_framebuffer(renderer->cso);
  648.    cso_restore_viewport(renderer->cso);
  649.    cso_restore_blend(renderer->cso);
  650.    cso_restore_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
  651.    cso_restore_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
  652.    cso_restore_fragment_shader(renderer->cso);
  653.    cso_restore_vertex_shader(renderer->cso);
  654.  
  655.    renderer->state = RENDERER_STATE_INIT;
  656. }
  657.  
  658. /**
  659.  * Prepare the renderer for textured drawing.
  660.  */
  661. VGboolean renderer_drawtex_begin(struct renderer *renderer,
  662.                                  struct pipe_sampler_view *src)
  663. {
  664.    assert(renderer->state == RENDERER_STATE_INIT);
  665.  
  666.    if (!renderer_can_support(renderer, src->texture, PIPE_BIND_SAMPLER_VIEW))
  667.       return VG_FALSE;
  668.  
  669.    cso_save_blend(renderer->cso);
  670.    cso_save_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
  671.    cso_save_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
  672.    cso_save_fragment_shader(renderer->cso);
  673.    cso_save_vertex_shader(renderer->cso);
  674.  
  675.    renderer_set_blend(renderer, ~0);
  676.  
  677.    renderer_set_samplers(renderer, 1, &src);
  678.  
  679.    renderer_set_fs(renderer, RENDERER_FS_TEXTURE);
  680.    renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
  681.  
  682.    renderer_set_mvp(renderer, NULL);
  683.  
  684.    /* remember the texture size */
  685.    renderer->u.drawtex.tex_width = src->texture->width0;
  686.    renderer->u.drawtex.tex_height = src->texture->height0;
  687.    renderer->state = RENDERER_STATE_DRAWTEX;
  688.  
  689.    return VG_TRUE;
  690. }
  691.  
  692. /**
  693.  * Draw into the destination rectangle given by (x, y, w, h).  The texture is
  694.  * sampled from within the rectangle given by (sx, sy, sw, sh).
  695.  *
  696.  * The coordinates are in surface coordinates.
  697.  */
  698. void renderer_drawtex(struct renderer *renderer,
  699.                       VGint x, VGint y, VGint w, VGint h,
  700.                       VGint sx, VGint sy, VGint sw, VGint sh)
  701. {
  702.    assert(renderer->state == RENDERER_STATE_DRAWTEX);
  703.  
  704.    /* with scissoring */
  705.    renderer_quad_pos(renderer, x, y, x + w, y + h, VG_TRUE);
  706.    renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
  707.          renderer->u.drawtex.tex_width,
  708.          renderer->u.drawtex.tex_height);
  709.  
  710.    renderer_quad_draw(renderer);
  711. }
  712.  
  713. /**
  714.  * End textured drawing and restore the states.
  715.  */
  716. void renderer_drawtex_end(struct renderer *renderer)
  717. {
  718.    assert(renderer->state == RENDERER_STATE_DRAWTEX);
  719.  
  720.    cso_restore_blend(renderer->cso);
  721.    cso_restore_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
  722.    cso_restore_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
  723.    cso_restore_fragment_shader(renderer->cso);
  724.    cso_restore_vertex_shader(renderer->cso);
  725.  
  726.    renderer->state = RENDERER_STATE_INIT;
  727. }
  728.  
  729. /**
  730.  * Prepare the renderer for scissor update.  This will reset the depth buffer
  731.  * to 1.0f.
  732.  */
  733. VGboolean renderer_scissor_begin(struct renderer *renderer,
  734.                                  VGboolean restore_dsa)
  735. {
  736.    struct pipe_depth_stencil_alpha_state dsa;
  737.  
  738.    assert(renderer->state == RENDERER_STATE_INIT);
  739.  
  740.    if (restore_dsa)
  741.       cso_save_depth_stencil_alpha(renderer->cso);
  742.    cso_save_blend(renderer->cso);
  743.    cso_save_fragment_shader(renderer->cso);
  744.  
  745.    /* enable depth writes */
  746.    memset(&dsa, 0, sizeof(dsa));
  747.    dsa.depth.enabled = 1;
  748.    dsa.depth.writemask = 1;
  749.    dsa.depth.func = PIPE_FUNC_ALWAYS;
  750.    cso_set_depth_stencil_alpha(renderer->cso, &dsa);
  751.  
  752.    /* disable color writes */
  753.    renderer_set_blend(renderer, 0);
  754.    renderer_set_fs(renderer, RENDERER_FS_SCISSOR);
  755.  
  756.    renderer_set_mvp(renderer, NULL);
  757.  
  758.    renderer->u.scissor.restore_dsa = restore_dsa;
  759.    renderer->state = RENDERER_STATE_SCISSOR;
  760.  
  761.    /* clear the depth buffer to 1.0f */
  762.    renderer->pipe->clear(renderer->pipe,
  763.          PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0f, 0);
  764.  
  765.    return VG_TRUE;
  766. }
  767.  
  768. /**
  769.  * Add a scissor rectangle.  Depth values inside the rectangle will be set to
  770.  * 0.0f.
  771.  */
  772. void renderer_scissor(struct renderer *renderer,
  773.                       VGint x, VGint y, VGint width, VGint height)
  774. {
  775.    assert(renderer->state == RENDERER_STATE_SCISSOR);
  776.  
  777.    renderer_quad_pos(renderer, x, y, x + width, y + height, VG_FALSE);
  778.    renderer_quad_draw(renderer);
  779. }
  780.  
  781. /**
  782.  * End scissor update and restore the states.
  783.  */
  784. void renderer_scissor_end(struct renderer *renderer)
  785. {
  786.    assert(renderer->state == RENDERER_STATE_SCISSOR);
  787.  
  788.    if (renderer->u.scissor.restore_dsa)
  789.       cso_restore_depth_stencil_alpha(renderer->cso);
  790.    cso_restore_blend(renderer->cso);
  791.    cso_restore_fragment_shader(renderer->cso);
  792.  
  793.    renderer->state = RENDERER_STATE_INIT;
  794. }
  795.  
  796. /**
  797.  * Prepare the renderer for clearing.
  798.  */
  799. VGboolean renderer_clear_begin(struct renderer *renderer)
  800. {
  801.    assert(renderer->state == RENDERER_STATE_INIT);
  802.  
  803.    cso_save_blend(renderer->cso);
  804.    cso_save_fragment_shader(renderer->cso);
  805.    cso_save_vertex_shader(renderer->cso);
  806.  
  807.    renderer_set_blend(renderer, ~0);
  808.    renderer_set_fs(renderer, RENDERER_FS_COLOR);
  809.    renderer_set_vs(renderer, RENDERER_VS_COLOR);
  810.  
  811.    renderer_set_mvp(renderer, NULL);
  812.  
  813.    renderer->state = RENDERER_STATE_CLEAR;
  814.  
  815.    return VG_TRUE;
  816. }
  817.  
  818. /**
  819.  * Clear the framebuffer with the specified region and color.
  820.  *
  821.  * The coordinates are in surface coordinates.
  822.  */
  823. void renderer_clear(struct renderer *renderer,
  824.                     VGint x, VGint y, VGint width, VGint height,
  825.                     const VGfloat color[4])
  826. {
  827.    VGuint i;
  828.  
  829.    assert(renderer->state == RENDERER_STATE_CLEAR);
  830.  
  831.    renderer_quad_pos(renderer, x, y, x + width, y + height, VG_TRUE);
  832.    for (i = 0; i < 4; i++)
  833.       memcpy(renderer->vertices[i][1], color, sizeof(VGfloat) * 4);
  834.  
  835.    renderer_quad_draw(renderer);
  836. }
  837.  
  838. /**
  839.  * End clearing and retore the states.
  840.  */
  841. void renderer_clear_end(struct renderer *renderer)
  842. {
  843.    assert(renderer->state == RENDERER_STATE_CLEAR);
  844.  
  845.    cso_restore_blend(renderer->cso);
  846.    cso_restore_fragment_shader(renderer->cso);
  847.    cso_restore_vertex_shader(renderer->cso);
  848.  
  849.    renderer->state = RENDERER_STATE_INIT;
  850. }
  851.  
  852. /**
  853.  * Prepare the renderer for image filtering.
  854.  */
  855. VGboolean renderer_filter_begin(struct renderer *renderer,
  856.                                 struct pipe_resource *dst,
  857.                                 VGboolean y0_top,
  858.                                 VGbitfield channel_mask,
  859.                                 const struct pipe_sampler_state **samplers,
  860.                                 struct pipe_sampler_view **views,
  861.                                 VGint num_samplers,
  862.                                 void *fs,
  863.                                 const void *const_buffer,
  864.                                 VGint const_buffer_len)
  865. {
  866.    struct pipe_surface *surf, surf_tmpl;
  867.  
  868.    assert(renderer->state == RENDERER_STATE_INIT);
  869.  
  870.    if (!fs)
  871.       return VG_FALSE;
  872.    if (!renderer_can_support(renderer, dst, PIPE_BIND_RENDER_TARGET))
  873.       return VG_FALSE;
  874.  
  875.    u_surface_default_template(&surf_tmpl, dst);
  876.    surf = renderer->pipe->create_surface(renderer->pipe, dst, &surf_tmpl);
  877.    if (!surf)
  878.       return VG_FALSE;
  879.  
  880.    cso_save_framebuffer(renderer->cso);
  881.    cso_save_viewport(renderer->cso);
  882.    cso_save_blend(renderer->cso);
  883.  
  884.    /* set the image as the target */
  885.    renderer_set_target(renderer, surf, NULL, y0_top);
  886.    pipe_surface_reference(&surf, NULL);
  887.  
  888.    renderer_set_blend(renderer, channel_mask);
  889.  
  890.    if (num_samplers) {
  891.       struct pipe_resource *tex;
  892.  
  893.       cso_save_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
  894.       cso_save_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
  895.       cso_save_fragment_shader(renderer->cso);
  896.       cso_save_vertex_shader(renderer->cso);
  897.  
  898.       renderer_set_custom_fs(renderer, fs,
  899.                              samplers, views, num_samplers,
  900.                              const_buffer, const_buffer_len);
  901.       renderer_set_vs(renderer, RENDERER_VS_TEXTURE);
  902.  
  903.       tex = views[0]->texture;
  904.       renderer->u.filter.tex_width = tex->width0;
  905.       renderer->u.filter.tex_height = tex->height0;
  906.       renderer->u.filter.use_sampler = VG_TRUE;
  907.    }
  908.    else {
  909.       cso_save_fragment_shader(renderer->cso);
  910.  
  911.       renderer_set_custom_fs(renderer, fs, NULL, NULL, 0,
  912.                              const_buffer, const_buffer_len);
  913.  
  914.       renderer->u.filter.use_sampler = VG_FALSE;
  915.    }
  916.  
  917.    renderer_set_mvp(renderer, NULL);
  918.  
  919.    renderer->state = RENDERER_STATE_FILTER;
  920.  
  921.    return VG_TRUE;
  922. }
  923.  
  924. /**
  925.  * Draw into a rectangle of the destination with the specified region of the
  926.  * texture(s).
  927.  *
  928.  * The coordinates are in surface coordinates.
  929.  */
  930. void renderer_filter(struct renderer *renderer,
  931.                     VGint x, VGint y, VGint w, VGint h,
  932.                     VGint sx, VGint sy, VGint sw, VGint sh)
  933. {
  934.    assert(renderer->state == RENDERER_STATE_FILTER);
  935.  
  936.    renderer_quad_pos(renderer, x, y, x + w, y + h, VG_FALSE);
  937.    if (renderer->u.filter.use_sampler) {
  938.       renderer_quad_texcoord(renderer, sx, sy, sx + sw, sy + sh,
  939.             renderer->u.filter.tex_width,
  940.             renderer->u.filter.tex_height);
  941.    }
  942.  
  943.    renderer_quad_draw(renderer);
  944. }
  945.  
  946. /**
  947.  * End image filtering and restore the states.
  948.  */
  949. void renderer_filter_end(struct renderer *renderer)
  950. {
  951.    assert(renderer->state == RENDERER_STATE_FILTER);
  952.  
  953.    if (renderer->u.filter.use_sampler) {
  954.       cso_restore_samplers(renderer->cso, PIPE_SHADER_FRAGMENT);
  955.       cso_restore_sampler_views(renderer->cso, PIPE_SHADER_FRAGMENT);
  956.       cso_restore_vertex_shader(renderer->cso);
  957.    }
  958.  
  959.    cso_restore_framebuffer(renderer->cso);
  960.    cso_restore_viewport(renderer->cso);
  961.    cso_restore_blend(renderer->cso);
  962.    cso_restore_fragment_shader(renderer->cso);
  963.  
  964.    renderer->state = RENDERER_STATE_INIT;
  965. }
  966.  
  967. /**
  968.  * Prepare the renderer for polygon silhouette rendering.
  969.  */
  970. VGboolean renderer_polygon_stencil_begin(struct renderer *renderer,
  971.                                          struct pipe_vertex_element *velem,
  972.                                          VGFillRule rule,
  973.                                          VGboolean restore_dsa)
  974. {
  975.    struct pipe_depth_stencil_alpha_state *dsa;
  976.    VGboolean manual_two_sides;
  977.  
  978.    assert(renderer->state == RENDERER_STATE_INIT);
  979.  
  980.    cso_save_vertex_elements(renderer->cso);
  981.    cso_save_blend(renderer->cso);
  982.    cso_save_depth_stencil_alpha(renderer->cso);
  983.  
  984.    cso_set_vertex_elements(renderer->cso, 1, velem);
  985.  
  986.    /* disable color writes */
  987.    renderer_set_blend(renderer, 0);
  988.  
  989.    manual_two_sides = VG_FALSE;
  990.    dsa = &renderer->u.polygon_stencil.dsa;
  991.    memset(dsa, 0, sizeof(*dsa));
  992.    if (rule == VG_EVEN_ODD) {
  993.       dsa->stencil[0].enabled = 1;
  994.       dsa->stencil[0].writemask = 1;
  995.       dsa->stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
  996.       dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
  997.       dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT;
  998.       dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
  999.       dsa->stencil[0].valuemask = ~0;
  1000.    }
  1001.    else {
  1002.       assert(rule == VG_NON_ZERO);
  1003.  
  1004.       /* front face */
  1005.       dsa->stencil[0].enabled = 1;
  1006.       dsa->stencil[0].writemask = ~0;
  1007.       dsa->stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
  1008.       dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
  1009.       dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
  1010.       dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
  1011.       dsa->stencil[0].valuemask = ~0;
  1012.  
  1013.       if (renderer->pipe->screen->get_param(renderer->pipe->screen,
  1014.                                             PIPE_CAP_TWO_SIDED_STENCIL)) {
  1015.          /* back face */
  1016.          dsa->stencil[1] = dsa->stencil[0];
  1017.          dsa->stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
  1018.       }
  1019.       else {
  1020.          manual_two_sides = VG_TRUE;
  1021.       }
  1022.    }
  1023.    cso_set_depth_stencil_alpha(renderer->cso, dsa);
  1024.  
  1025.    if (manual_two_sides)
  1026.       cso_save_rasterizer(renderer->cso);
  1027.  
  1028.    renderer->u.polygon_stencil.manual_two_sides = manual_two_sides;
  1029.    renderer->u.polygon_stencil.restore_dsa = restore_dsa;
  1030.    renderer->state = RENDERER_STATE_POLYGON_STENCIL;
  1031.  
  1032.    return VG_TRUE;
  1033. }
  1034.  
  1035. /**
  1036.  * Render a polygon silhouette to stencil buffer.
  1037.  */
  1038. void renderer_polygon_stencil(struct renderer *renderer,
  1039.                               struct pipe_vertex_buffer *vbuf,
  1040.                               VGuint mode, VGuint start, VGuint count)
  1041. {
  1042.    assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL);
  1043.  
  1044.    cso_set_vertex_buffers(renderer->cso, 0, 1, vbuf);
  1045.  
  1046.    if (!renderer->u.polygon_stencil.manual_two_sides) {
  1047.       cso_draw_arrays(renderer->cso, mode, start, count);
  1048.    }
  1049.    else {
  1050.       struct pipe_rasterizer_state raster;
  1051.       struct pipe_depth_stencil_alpha_state dsa;
  1052.  
  1053.       raster = renderer->g3d.rasterizer;
  1054.       dsa = renderer->u.polygon_stencil.dsa;
  1055.  
  1056.       /* front */
  1057.       raster.cull_face = PIPE_FACE_BACK;
  1058.       dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
  1059.  
  1060.       cso_set_rasterizer(renderer->cso, &raster);
  1061.       cso_set_depth_stencil_alpha(renderer->cso, &dsa);
  1062.       cso_draw_arrays(renderer->cso, mode, start, count);
  1063.  
  1064.       /* back */
  1065.       raster.cull_face = PIPE_FACE_FRONT;
  1066.       dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
  1067.  
  1068.       cso_set_rasterizer(renderer->cso, &raster);
  1069.       cso_set_depth_stencil_alpha(renderer->cso, &dsa);
  1070.       cso_draw_arrays(renderer->cso, mode, start, count);
  1071.    }
  1072. }
  1073.  
  1074. /**
  1075.  * End polygon silhouette rendering.
  1076.  */
  1077. void renderer_polygon_stencil_end(struct renderer *renderer)
  1078. {
  1079.    assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL);
  1080.  
  1081.    if (renderer->u.polygon_stencil.manual_two_sides)
  1082.       cso_restore_rasterizer(renderer->cso);
  1083.  
  1084.    cso_restore_vertex_elements(renderer->cso);
  1085.  
  1086.    /* restore color writes */
  1087.    cso_restore_blend(renderer->cso);
  1088.  
  1089.    if (renderer->u.polygon_stencil.restore_dsa)
  1090.       cso_restore_depth_stencil_alpha(renderer->cso);
  1091.  
  1092.    renderer->state = RENDERER_STATE_INIT;
  1093. }
  1094.  
  1095. /**
  1096.  * Prepare the renderer for polygon filling.
  1097.  */
  1098. VGboolean renderer_polygon_fill_begin(struct renderer *renderer,
  1099.                                       VGboolean save_dsa)
  1100. {
  1101.    struct pipe_depth_stencil_alpha_state dsa;
  1102.  
  1103.    assert(renderer->state == RENDERER_STATE_INIT);
  1104.  
  1105.    if (save_dsa)
  1106.       cso_save_depth_stencil_alpha(renderer->cso);
  1107.  
  1108.    /* setup stencil ops */
  1109.    memset(&dsa, 0, sizeof(dsa));
  1110.    dsa.stencil[0].enabled = 1;
  1111.    dsa.stencil[0].func = PIPE_FUNC_NOTEQUAL;
  1112.    dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
  1113.    dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
  1114.    dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
  1115.    dsa.stencil[0].valuemask = ~0;
  1116.    dsa.stencil[0].writemask = ~0;
  1117.    dsa.depth = renderer->g3d.dsa.depth;
  1118.    cso_set_depth_stencil_alpha(renderer->cso, &dsa);
  1119.  
  1120.    renderer->state = RENDERER_STATE_POLYGON_FILL;
  1121.  
  1122.    return VG_TRUE;
  1123. }
  1124.  
  1125. /**
  1126.  * Fill a polygon.
  1127.  */
  1128. void renderer_polygon_fill(struct renderer *renderer,
  1129.                            VGfloat min_x, VGfloat min_y,
  1130.                            VGfloat max_x, VGfloat max_y)
  1131. {
  1132.    assert(renderer->state == RENDERER_STATE_POLYGON_FILL);
  1133.  
  1134.    renderer_quad_pos(renderer, min_x, min_y, max_x, max_y, VG_TRUE);
  1135.    renderer_quad_draw(renderer);
  1136. }
  1137.  
  1138. /**
  1139.  * End polygon filling.
  1140.  */
  1141. void renderer_polygon_fill_end(struct renderer *renderer)
  1142. {
  1143.    assert(renderer->state == RENDERER_STATE_POLYGON_FILL);
  1144.  
  1145.    cso_restore_depth_stencil_alpha(renderer->cso);
  1146.  
  1147.    renderer->state = RENDERER_STATE_INIT;
  1148. }
  1149.  
  1150. struct renderer * renderer_create(struct vg_context *owner)
  1151. {
  1152.    struct renderer *renderer;
  1153.    struct pipe_rasterizer_state *raster;
  1154.    struct pipe_stencil_ref sr;
  1155.    VGint i;
  1156.  
  1157.    renderer = CALLOC_STRUCT(renderer);
  1158.    if (!renderer)
  1159.       return NULL;
  1160.  
  1161.    renderer->pipe = owner->pipe;
  1162.    renderer->cso = owner->cso_context;
  1163.  
  1164.    /* init vertex data that doesn't change */
  1165.    for (i = 0; i < 4; i++)
  1166.       renderer->vertices[i][0][3] = 1.0f; /* w */
  1167.  
  1168.    for (i = 0; i < 2; i++) {
  1169.       renderer->velems[i].src_offset = i * 4 * sizeof(float);
  1170.       renderer->velems[i].instance_divisor = 0;
  1171.       renderer->velems[i].vertex_buffer_index = 0;
  1172.       renderer->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  1173.    }
  1174.    cso_set_vertex_elements(renderer->cso, 2, renderer->velems);
  1175.  
  1176.    /* GL rasterization rules */
  1177.    raster = &renderer->g3d.rasterizer;
  1178.    memset(raster, 0, sizeof(*raster));
  1179.    raster->half_pixel_center = 1;
  1180.    raster->bottom_edge_rule = 1;
  1181.    raster->depth_clip = 1;
  1182.    cso_set_rasterizer(renderer->cso, raster);
  1183.  
  1184.    /* fixed at 0 */
  1185.    memset(&sr, 0, sizeof(sr));
  1186.    cso_set_stencil_ref(renderer->cso, &sr);
  1187.  
  1188.    renderer_set_vs(renderer, RENDERER_VS_PLAIN);
  1189.  
  1190.    renderer->state = RENDERER_STATE_INIT;
  1191.  
  1192.    return renderer;
  1193. }
  1194.  
  1195. void renderer_destroy(struct renderer *ctx)
  1196. {
  1197.    int i;
  1198.  
  1199.    for (i = 0; i < NUM_RENDERER_VS; i++) {
  1200.       if (ctx->cached_vs[i])
  1201.          cso_delete_vertex_shader(ctx->cso, ctx->cached_vs[i]);
  1202.    }
  1203.    for (i = 0; i < NUM_RENDERER_FS; i++) {
  1204.       if (ctx->cached_fs[i])
  1205.          cso_delete_fragment_shader(ctx->cso, ctx->cached_fs[i]);
  1206.    }
  1207.  
  1208.    pipe_resource_reference(&ctx->vs_cbuf, NULL);
  1209.    pipe_resource_reference(&ctx->fs_cbuf, NULL);
  1210.  
  1211.    FREE(ctx);
  1212. }
  1213.  
  1214. static void update_clip_state(struct renderer *renderer,
  1215.                               const struct vg_state *state)
  1216. {
  1217.    struct pipe_depth_stencil_alpha_state *dsa = &renderer->g3d.dsa;
  1218.  
  1219.    memset(dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
  1220.  
  1221.    if (state->scissoring) {
  1222.       struct pipe_framebuffer_state *fb = &renderer->g3d.fb;
  1223.       int i;
  1224.  
  1225.       renderer_scissor_begin(renderer, VG_FALSE);
  1226.  
  1227.       for (i = 0; i < state->scissor_rects_num; ++i) {
  1228.          const float x      = state->scissor_rects[i * 4 + 0].f;
  1229.          const float y      = state->scissor_rects[i * 4 + 1].f;
  1230.          const float width  = state->scissor_rects[i * 4 + 2].f;
  1231.          const float height = state->scissor_rects[i * 4 + 3].f;
  1232.          VGint x0, y0, x1, y1, iw, ih;
  1233.  
  1234.          x0 = (VGint) x;
  1235.          y0 = (VGint) y;
  1236.          if (x0 < 0)
  1237.             x0 = 0;
  1238.          if (y0 < 0)
  1239.             y0 = 0;
  1240.  
  1241.          /* note that x1 and y1 are exclusive */
  1242.          x1 = (VGint) ceilf(x + width);
  1243.          y1 = (VGint) ceilf(y + height);
  1244.          if (x1 > fb->width)
  1245.             x1 = fb->width;
  1246.          if (y1 > fb->height)
  1247.             y1 = fb->height;
  1248.  
  1249.          iw = x1 - x0;
  1250.          ih = y1 - y0;
  1251.          if (iw > 0 && ih> 0 )
  1252.             renderer_scissor(renderer, x0, y0, iw, ih);
  1253.       }
  1254.  
  1255.       renderer_scissor_end(renderer);
  1256.  
  1257.       dsa->depth.enabled = 1; /* glEnable(GL_DEPTH_TEST); */
  1258.       dsa->depth.writemask = 0;/*glDepthMask(FALSE);*/
  1259.       dsa->depth.func = PIPE_FUNC_GEQUAL;
  1260.    }
  1261. }
  1262.  
  1263. static void renderer_validate_blend(struct renderer *renderer,
  1264.                                      const struct vg_state *state,
  1265.                                      enum pipe_format fb_format)
  1266. {
  1267.    struct pipe_blend_state blend;
  1268.  
  1269.    memset(&blend, 0, sizeof(blend));
  1270.    blend.rt[0].colormask = PIPE_MASK_RGBA;
  1271.    blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
  1272.    blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
  1273.    blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
  1274.    blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
  1275.  
  1276.    /* TODO alpha masking happens after blending? */
  1277.  
  1278.    switch (state->blend_mode) {
  1279.    case VG_BLEND_SRC:
  1280.       blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
  1281.       blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
  1282.       blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
  1283.       blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
  1284.       break;
  1285.    case VG_BLEND_SRC_OVER:
  1286.       /* use the blend state only when there is no alpha channel */
  1287.       if (!util_format_has_alpha(fb_format)) {
  1288.          blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_SRC_ALPHA;
  1289.          blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
  1290.          blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
  1291.          blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
  1292.          blend.rt[0].blend_enable = 1;
  1293.       }
  1294.       break;
  1295.    case VG_BLEND_SRC_IN:
  1296.       blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
  1297.       blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
  1298.       blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
  1299.       blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
  1300.       blend.rt[0].blend_enable = 1;
  1301.       break;
  1302.    case VG_BLEND_DST_IN:
  1303.       blend.rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ZERO;
  1304.       blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
  1305.       blend.rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ONE;
  1306.       blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
  1307.       blend.rt[0].blend_enable = 1;
  1308.       break;
  1309.    case VG_BLEND_DST_OVER:
  1310.    case VG_BLEND_MULTIPLY:
  1311.    case VG_BLEND_SCREEN:
  1312.    case VG_BLEND_DARKEN:
  1313.    case VG_BLEND_LIGHTEN:
  1314.    case VG_BLEND_ADDITIVE:
  1315.       /* need a shader */
  1316.       break;
  1317.    default:
  1318.       assert(!"not implemented blend mode");
  1319.       break;
  1320.    }
  1321.  
  1322.    cso_set_blend(renderer->cso, &blend);
  1323. }
  1324.  
  1325. /**
  1326.  * Propogate OpenVG state changes to the renderer.  Only framebuffer, blending
  1327.  * and scissoring states are relevant here.
  1328.  */
  1329. void renderer_validate(struct renderer *renderer,
  1330.                        VGbitfield dirty,
  1331.                        const struct st_framebuffer *stfb,
  1332.                        const struct vg_state *state)
  1333. {
  1334.    assert(renderer->state == RENDERER_STATE_INIT);
  1335.  
  1336.    dirty |= renderer->dirty;
  1337.    renderer->dirty = 0;
  1338.  
  1339.    if (dirty & FRAMEBUFFER_DIRTY) {
  1340.       struct pipe_framebuffer_state *fb = &renderer->g3d.fb;
  1341.       struct matrix *proj = &renderer->projection;
  1342.  
  1343.       memset(fb, 0, sizeof(struct pipe_framebuffer_state));
  1344.       fb->width  = stfb->width;
  1345.       fb->height = stfb->height;
  1346.       fb->nr_cbufs = 1;
  1347.       fb->cbufs[0] = stfb->strb->surface;
  1348.       fb->zsbuf = stfb->dsrb->surface;
  1349.  
  1350.       cso_set_framebuffer(renderer->cso, fb);
  1351.       vg_set_viewport(renderer, VEGA_Y0_BOTTOM);
  1352.  
  1353.       matrix_load_identity(proj);
  1354.       matrix_translate(proj, -1.0f, -1.0f);
  1355.       matrix_scale(proj, 2.0f / fb->width, 2.0f / fb->height);
  1356.  
  1357.       /* we also got a new depth buffer */
  1358.       if (dirty & DEPTH_STENCIL_DIRTY) {
  1359.          renderer->pipe->clear(renderer->pipe,
  1360.                PIPE_CLEAR_DEPTHSTENCIL, NULL, 0.0, 0);
  1361.       }
  1362.    }
  1363.  
  1364.    /* must be last because it renders to the depth buffer*/
  1365.    if (dirty & DEPTH_STENCIL_DIRTY) {
  1366.       update_clip_state(renderer, state);
  1367.       cso_set_depth_stencil_alpha(renderer->cso, &renderer->g3d.dsa);
  1368.    }
  1369.  
  1370.    if (dirty & BLEND_DIRTY)
  1371.       renderer_validate_blend(renderer, state, stfb->strb->format);
  1372. }
  1373.  
  1374. /**
  1375.  * Prepare the renderer for OpenVG pipeline.
  1376.  */
  1377. void renderer_validate_for_shader(struct renderer *renderer,
  1378.                                   const struct pipe_sampler_state **samplers,
  1379.                                   struct pipe_sampler_view **views,
  1380.                                   VGint num_samplers,
  1381.                                   const struct matrix *modelview,
  1382.                                   void *fs,
  1383.                                   const void *const_buffer,
  1384.                                   VGint const_buffer_len)
  1385. {
  1386.    struct matrix mvp = renderer->projection;
  1387.  
  1388.    /* will be used in POLYGON_STENCIL and POLYGON_FILL */
  1389.    matrix_mult(&mvp, modelview);
  1390.    renderer_set_mvp(renderer, &mvp);
  1391.  
  1392.    renderer_set_custom_fs(renderer, fs,
  1393.                           samplers, views, num_samplers,
  1394.                           const_buffer, const_buffer_len);
  1395. }
  1396.  
  1397. void renderer_validate_for_mask_rendering(struct renderer *renderer,
  1398.                                           struct pipe_surface *dst,
  1399.                                           const struct matrix *modelview)
  1400. {
  1401.    struct matrix mvp = renderer->projection;
  1402.  
  1403.    /* will be used in POLYGON_STENCIL and POLYGON_FILL */
  1404.    matrix_mult(&mvp, modelview);
  1405.    renderer_set_mvp(renderer, &mvp);
  1406.  
  1407.    renderer_set_target(renderer, dst, renderer->g3d.fb.zsbuf, VG_FALSE);
  1408.    renderer_set_blend(renderer, ~0);
  1409.    renderer_set_fs(renderer, RENDERER_FS_WHITE);
  1410.  
  1411.    /* set internal dirty flags (hacky!) */
  1412.    renderer->dirty = FRAMEBUFFER_DIRTY | BLEND_DIRTY;
  1413. }
  1414.  
  1415. void renderer_copy_surface(struct renderer *ctx,
  1416.                            struct pipe_surface *src,
  1417.                            int srcX0, int srcY0,
  1418.                            int srcX1, int srcY1,
  1419.                            struct pipe_surface *dst,
  1420.                            int dstX0, int dstY0,
  1421.                            int dstX1, int dstY1,
  1422.                            float z, unsigned filter)
  1423. {
  1424.    struct pipe_context *pipe = ctx->pipe;
  1425.    struct pipe_screen *screen = pipe->screen;
  1426.    struct pipe_sampler_view view_templ;
  1427.    struct pipe_sampler_view *view;
  1428.    struct pipe_box src_box;
  1429.    struct pipe_resource texTemp, *tex;
  1430.    const struct pipe_framebuffer_state *fb = &ctx->g3d.fb;
  1431.    const int srcW = abs(srcX1 - srcX0);
  1432.    const int srcH = abs(srcY1 - srcY0);
  1433.    const int srcLeft = MIN2(srcX0, srcX1);
  1434.    const int srcTop = MIN2(srcY0, srcY1);
  1435.  
  1436.    assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
  1437.           filter == PIPE_TEX_MIPFILTER_LINEAR);
  1438.  
  1439.    if (srcLeft != srcX0) {
  1440.       /* left-right flip */
  1441.       int tmp = dstX0;
  1442.       dstX0 = dstX1;
  1443.       dstX1 = tmp;
  1444.    }
  1445.  
  1446.    if (srcTop != srcY0) {
  1447.       /* up-down flip */
  1448.       int tmp = dstY0;
  1449.       dstY0 = dstY1;
  1450.       dstY1 = tmp;
  1451.    }
  1452.  
  1453.    assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
  1454.                                       0, PIPE_BIND_SAMPLER_VIEW));
  1455.    assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
  1456.                                       0, PIPE_BIND_SAMPLER_VIEW));
  1457.    assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
  1458.                                       0, PIPE_BIND_RENDER_TARGET));
  1459.  
  1460.    /*
  1461.     * XXX for now we're always creating a temporary texture.
  1462.     * Strictly speaking that's not always needed.
  1463.     */
  1464.  
  1465.    /* create temp texture */
  1466.    memset(&texTemp, 0, sizeof(texTemp));
  1467.    texTemp.target = PIPE_TEXTURE_2D;
  1468.    texTemp.format = src->format;
  1469.    texTemp.last_level = 0;
  1470.    texTemp.width0 = srcW;
  1471.    texTemp.height0 = srcH;
  1472.    texTemp.depth0 = 1;
  1473.    texTemp.array_size = 1;
  1474.    texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
  1475.  
  1476.    tex = screen->resource_create(screen, &texTemp);
  1477.    if (!tex)
  1478.       return;
  1479.  
  1480.    u_sampler_view_default_template(&view_templ, tex, tex->format);
  1481.    view = pipe->create_sampler_view(pipe, tex, &view_templ);
  1482.  
  1483.    if (!view)
  1484.       return;
  1485.  
  1486.    u_box_2d_zslice(srcLeft, srcTop, src->u.tex.first_layer, srcW, srcH, &src_box);
  1487.  
  1488.    pipe->resource_copy_region(pipe,
  1489.                               tex, 0, 0, 0, 0,  /* dest */
  1490.                               src->texture, 0, &src_box);
  1491.  
  1492.    assert(floatsEqual(z, 0.0f));
  1493.  
  1494.    /* draw */
  1495.    if (fb->cbufs[0] == dst) {
  1496.       /* transform back to surface coordinates */
  1497.       dstY0 = dst->height - dstY0;
  1498.       dstY1 = dst->height - dstY1;
  1499.  
  1500.       if (renderer_drawtex_begin(ctx, view)) {
  1501.          renderer_drawtex(ctx,
  1502.                dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0,
  1503.                0, 0, view->texture->width0, view->texture->height0);
  1504.          renderer_drawtex_end(ctx);
  1505.       }
  1506.    }
  1507.    else {
  1508.       if (renderer_copy_begin(ctx, dst, VG_TRUE, view)) {
  1509.          renderer_copy(ctx,
  1510.                dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0,
  1511.                0, 0, view->texture->width0, view->texture->height0);
  1512.          renderer_copy_end(ctx);
  1513.       }
  1514.    }
  1515. }
  1516.  
  1517. void renderer_texture_quad(struct renderer *r,
  1518.                            struct pipe_resource *tex,
  1519.                            VGfloat x1offset, VGfloat y1offset,
  1520.                            VGfloat x2offset, VGfloat y2offset,
  1521.                            VGfloat x1, VGfloat y1,
  1522.                            VGfloat x2, VGfloat y2,
  1523.                            VGfloat x3, VGfloat y3,
  1524.                            VGfloat x4, VGfloat y4)
  1525. {
  1526.    const VGfloat z = 0.0f;
  1527.  
  1528.    assert(r->state == RENDERER_STATE_INIT);
  1529.    assert(tex->width0 != 0);
  1530.    assert(tex->height0 != 0);
  1531.  
  1532.    cso_save_vertex_shader(r->cso);
  1533.  
  1534.    renderer_set_vs(r, RENDERER_VS_TEXTURE);
  1535.  
  1536.    /* manually set up positions */
  1537.    r->vertices[0][0][0] = x1;
  1538.    r->vertices[0][0][1] = y1;
  1539.    r->vertices[0][0][2] = z;
  1540.  
  1541.    r->vertices[1][0][0] = x2;
  1542.    r->vertices[1][0][1] = y2;
  1543.    r->vertices[1][0][2] = z;
  1544.  
  1545.    r->vertices[2][0][0] = x3;
  1546.    r->vertices[2][0][1] = y3;
  1547.    r->vertices[2][0][2] = z;
  1548.  
  1549.    r->vertices[3][0][0] = x4;
  1550.    r->vertices[3][0][1] = y4;
  1551.    r->vertices[3][0][2] = z;
  1552.  
  1553.    /* texcoords */
  1554.    renderer_quad_texcoord(r, x1offset, y1offset,
  1555.          x2offset, y2offset, tex->width0, tex->height0);
  1556.  
  1557.    renderer_quad_draw(r);
  1558.  
  1559.    cso_restore_vertex_shader(r->cso);
  1560. }
  1561.