Home | History | Annotate | Download | only in svga
      1 /**********************************************************
      2  * Copyright 2008-2009 VMware, Inc.  All rights reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person
      5  * obtaining a copy of this software and associated documentation
      6  * files (the "Software"), to deal in the Software without
      7  * restriction, including without limitation the rights to use, copy,
      8  * modify, merge, publish, distribute, sublicense, and/or sell copies
      9  * of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be
     13  * included in all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  **********************************************************/
     25 
     26 #include "draw/draw_context.h"
     27 #include "draw/draw_vbuf.h"
     28 #include "util/u_inlines.h"
     29 #include "pipe/p_state.h"
     30 
     31 #include "svga_context.h"
     32 #include "svga_swtnl.h"
     33 #include "svga_state.h"
     34 #include "svga_swtnl_private.h"
     35 
     36 
     37 
     38 enum pipe_error
     39 svga_swtnl_draw_vbo(struct svga_context *svga,
     40                     const struct pipe_draw_info *info)
     41 {
     42    struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
     43    struct pipe_transfer *ib_transfer = NULL;
     44    struct pipe_transfer *cb_transfer = NULL;
     45    struct draw_context *draw = svga->swtnl.draw;
     46    unsigned i;
     47    const void *map;
     48    enum pipe_error ret;
     49 
     50    assert(!svga->dirty);
     51    assert(svga->state.sw.need_swtnl);
     52    assert(draw);
     53 
     54    /* Make sure that the need_swtnl flag does not go away */
     55    svga->state.sw.in_swtnl_draw = TRUE;
     56 
     57    ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW);
     58    if (ret != PIPE_OK) {
     59       svga_context_flush(svga, NULL);
     60       ret = svga_update_state(svga, SVGA_STATE_SWTNL_DRAW);
     61       svga->swtnl.new_vbuf = TRUE;
     62       assert(ret == PIPE_OK);
     63    }
     64 
     65    /*
     66     * Map vertex buffers
     67     */
     68    for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
     69       if (svga->curr.vb[i].buffer) {
     70          map = pipe_buffer_map(&svga->pipe,
     71                                svga->curr.vb[i].buffer,
     72                                PIPE_TRANSFER_READ,
     73                                &vb_transfer[i]);
     74 
     75          draw_set_mapped_vertex_buffer(draw, i, map);
     76       }
     77    }
     78 
     79    /* Map index buffer, if present */
     80    map = NULL;
     81    if (info->indexed && svga->curr.ib.buffer) {
     82       map = pipe_buffer_map(&svga->pipe, svga->curr.ib.buffer,
     83                             PIPE_TRANSFER_READ,
     84                             &ib_transfer);
     85       draw_set_indexes(draw,
     86                        (const ubyte *) map + svga->curr.ib.offset,
     87                        svga->curr.ib.index_size);
     88    }
     89 
     90    if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
     91       map = pipe_buffer_map(&svga->pipe,
     92                             svga->curr.cb[PIPE_SHADER_VERTEX],
     93                             PIPE_TRANSFER_READ,
     94 			    &cb_transfer);
     95       assert(map);
     96       draw_set_mapped_constant_buffer(
     97          draw, PIPE_SHADER_VERTEX, 0,
     98          map,
     99          svga->curr.cb[PIPE_SHADER_VERTEX]->width0);
    100    }
    101 
    102    draw_vbo(draw, info);
    103 
    104    draw_flush(svga->swtnl.draw);
    105 
    106    /* Ensure the draw module didn't touch this */
    107    assert(i == svga->curr.num_vertex_buffers);
    108 
    109    /*
    110     * unmap vertex/index buffers
    111     */
    112    for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
    113       if (svga->curr.vb[i].buffer) {
    114          pipe_buffer_unmap(&svga->pipe, vb_transfer[i]);
    115          draw_set_mapped_vertex_buffer(draw, i, NULL);
    116       }
    117    }
    118 
    119    if (ib_transfer) {
    120       pipe_buffer_unmap(&svga->pipe, ib_transfer);
    121       draw_set_indexes(draw, NULL, 0);
    122    }
    123 
    124    if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
    125       pipe_buffer_unmap(&svga->pipe, cb_transfer);
    126    }
    127 
    128    /* Now safe to remove the need_swtnl flag in any update_state call */
    129    svga->state.sw.in_swtnl_draw = FALSE;
    130    svga->dirty |= SVGA_NEW_NEED_PIPELINE | SVGA_NEW_NEED_SWVFETCH;
    131 
    132    return ret;
    133 }
    134 
    135 
    136 
    137 
    138 boolean svga_init_swtnl( struct svga_context *svga )
    139 {
    140    svga->swtnl.backend = svga_vbuf_render_create(svga);
    141    if(!svga->swtnl.backend)
    142       goto fail;
    143 
    144    /*
    145     * Create drawing context and plug our rendering stage into it.
    146     */
    147    svga->swtnl.draw = draw_create(&svga->pipe);
    148    if (svga->swtnl.draw == NULL)
    149       goto fail;
    150 
    151 
    152    draw_set_rasterize_stage(svga->swtnl.draw,
    153                             draw_vbuf_stage( svga->swtnl.draw, svga->swtnl.backend ));
    154 
    155    draw_set_render(svga->swtnl.draw, svga->swtnl.backend);
    156 
    157    draw_install_aaline_stage(svga->swtnl.draw, &svga->pipe);
    158    draw_install_aapoint_stage(svga->swtnl.draw, &svga->pipe);
    159    draw_install_pstipple_stage(svga->swtnl.draw, &svga->pipe);
    160 
    161    if (debug_get_bool_option("SVGA_SWTNL_FSE", FALSE))
    162       draw_set_driver_clipping(svga->swtnl.draw, TRUE, TRUE, TRUE);
    163 
    164    return TRUE;
    165 
    166 fail:
    167    if (svga->swtnl.backend)
    168       svga->swtnl.backend->destroy( svga->swtnl.backend );
    169 
    170    if (svga->swtnl.draw)
    171       draw_destroy( svga->swtnl.draw );
    172 
    173    return FALSE;
    174 }
    175 
    176 
    177 void svga_destroy_swtnl( struct svga_context *svga )
    178 {
    179    draw_destroy( svga->swtnl.draw );
    180 }
    181