Home | History | Annotate | Download | only in llvmpipe
      1 /**************************************************************************
      2  *
      3  * Copyright 2010 VMware, Inc.
      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 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 "lp_context.h"
     29 #include "lp_state.h"
     30 #include "lp_texture.h"
     31 
     32 #include "util/u_memory.h"
     33 #include "draw/draw_context.h"
     34 
     35 
     36 static void *
     37 llvmpipe_create_stream_output_state(struct pipe_context *pipe,
     38                                     const struct pipe_stream_output_info *templ)
     39 {
     40    struct lp_so_state *so;
     41    so = (struct lp_so_state *) CALLOC_STRUCT(lp_so_state);
     42 
     43    if (so) {
     44       so->base.num_outputs = templ->num_outputs;
     45       memcpy(so->base.stride, templ->stride, sizeof(templ->stride));
     46       memcpy(so->base.output, templ->output,
     47              templ->num_outputs * sizeof(templ->output[0]));
     48    }
     49    return so;
     50 }
     51 
     52 static void
     53 llvmpipe_bind_stream_output_state(struct pipe_context *pipe,
     54                                   void *so)
     55 {
     56    struct llvmpipe_context *lp = llvmpipe_context(pipe);
     57    struct lp_so_state *lp_so = (struct lp_so_state *) so;
     58 
     59    lp->so = lp_so;
     60 
     61    lp->dirty |= LP_NEW_SO;
     62 
     63    if (lp_so)
     64       draw_set_so_state(lp->draw, &lp_so->base);
     65 }
     66 
     67 static void
     68 llvmpipe_delete_stream_output_state(struct pipe_context *pipe, void *so)
     69 {
     70    FREE( so );
     71 }
     72 
     73 static void
     74 llvmpipe_set_stream_output_buffers(struct pipe_context *pipe,
     75                                    struct pipe_resource **buffers,
     76                                    int *offsets,
     77                                    int num_buffers)
     78 {
     79    struct llvmpipe_context *lp = llvmpipe_context(pipe);
     80    int i;
     81    void *map_buffers[PIPE_MAX_SO_BUFFERS];
     82 
     83    assert(num_buffers <= PIPE_MAX_SO_BUFFERS);
     84    if (num_buffers > PIPE_MAX_SO_BUFFERS)
     85       num_buffers = PIPE_MAX_SO_BUFFERS;
     86 
     87    lp->dirty |= LP_NEW_SO_BUFFERS;
     88 
     89    for (i = 0; i < num_buffers; ++i) {
     90       void *mapped;
     91       struct llvmpipe_resource *res = llvmpipe_resource(buffers[i]);
     92 
     93       if (!res) {
     94          /* the whole call is invalid, bail out */
     95          lp->so_target.num_buffers = 0;
     96          draw_set_mapped_so_buffers(lp->draw, 0, 0);
     97          return;
     98       }
     99 
    100       lp->so_target.buffer[i] = res;
    101       lp->so_target.offset[i] = offsets[i];
    102       lp->so_target.so_count[i] = 0;
    103 
    104       mapped = res->data;
    105       if (offsets[i] >= 0)
    106          map_buffers[i] = ((char*)mapped) + offsets[i];
    107       else {
    108          /* this is a buffer append */
    109          assert(!"appending not implemented");
    110          map_buffers[i] = mapped;
    111       }
    112    }
    113    lp->so_target.num_buffers = num_buffers;
    114 
    115    draw_set_mapped_so_buffers(lp->draw, map_buffers, num_buffers);
    116 }
    117 
    118 void
    119 llvmpipe_init_so_funcs(struct llvmpipe_context *llvmpipe)
    120 {
    121 #if 0
    122    llvmpipe->pipe.create_stream_output_state =
    123       llvmpipe_create_stream_output_state;
    124    llvmpipe->pipe.bind_stream_output_state =
    125       llvmpipe_bind_stream_output_state;
    126    llvmpipe->pipe.delete_stream_output_state =
    127       llvmpipe_delete_stream_output_state;
    128 
    129    llvmpipe->pipe.set_stream_output_buffers =
    130       llvmpipe_set_stream_output_buffers;
    131 #else
    132    (void) llvmpipe_create_stream_output_state;
    133    (void) llvmpipe_bind_stream_output_state;
    134    (void) llvmpipe_delete_stream_output_state;
    135    (void) llvmpipe_set_stream_output_buffers;
    136 #endif
    137 }
    138