Home | History | Annotate | Download | only in softpipe
      1 /**************************************************************************
      2  *
      3  * Copyright 2007 VMware, Inc.
      4  * All Rights Reserved.
      5  * Copyright 2008 VMware, Inc.  All rights reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the
      9  * "Software"), to deal in the Software without restriction, including
     10  * without limitation the rights to use, copy, modify, merge, publish,
     11  * distribute, sub license, and/or sell copies of the Software, and to
     12  * permit persons to whom the Software is furnished to do so, subject to
     13  * the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the
     16  * next paragraph) shall be included in all copies or substantial portions
     17  * of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     22  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26  *
     27  **************************************************************************/
     28 
     29 /* Author:
     30  *    Keith Whitwell <keithw (at) vmware.com>
     31  */
     32 
     33 #include "draw/draw_context.h"
     34 #include "draw/draw_vbuf.h"
     35 #include "pipe/p_defines.h"
     36 #include "util/u_math.h"
     37 #include "util/u_memory.h"
     38 #include "util/u_pstipple.h"
     39 #include "util/u_inlines.h"
     40 #include "util/u_upload_mgr.h"
     41 #include "tgsi/tgsi_exec.h"
     42 #include "sp_buffer.h"
     43 #include "sp_clear.h"
     44 #include "sp_context.h"
     45 #include "sp_flush.h"
     46 #include "sp_prim_vbuf.h"
     47 #include "sp_state.h"
     48 #include "sp_surface.h"
     49 #include "sp_tile_cache.h"
     50 #include "sp_tex_tile_cache.h"
     51 #include "sp_texture.h"
     52 #include "sp_query.h"
     53 #include "sp_screen.h"
     54 #include "sp_tex_sample.h"
     55 #include "sp_image.h"
     56 
     57 static void
     58 softpipe_destroy( struct pipe_context *pipe )
     59 {
     60    struct softpipe_context *softpipe = softpipe_context( pipe );
     61    uint i, sh;
     62 
     63 #if DO_PSTIPPLE_IN_HELPER_MODULE
     64    if (softpipe->pstipple.sampler)
     65       pipe->delete_sampler_state(pipe, softpipe->pstipple.sampler);
     66 
     67    pipe_resource_reference(&softpipe->pstipple.texture, NULL);
     68    pipe_sampler_view_reference(&softpipe->pstipple.sampler_view, NULL);
     69 #endif
     70 
     71    if (softpipe->blitter) {
     72       util_blitter_destroy(softpipe->blitter);
     73    }
     74 
     75    if (softpipe->draw)
     76       draw_destroy( softpipe->draw );
     77 
     78    if (softpipe->quad.shade)
     79       softpipe->quad.shade->destroy( softpipe->quad.shade );
     80 
     81    if (softpipe->quad.depth_test)
     82       softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
     83 
     84    if (softpipe->quad.blend)
     85       softpipe->quad.blend->destroy( softpipe->quad.blend );
     86 
     87    if (softpipe->quad.pstipple)
     88       softpipe->quad.pstipple->destroy( softpipe->quad.pstipple );
     89 
     90    if (softpipe->pipe.stream_uploader)
     91       u_upload_destroy(softpipe->pipe.stream_uploader);
     92 
     93    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
     94       sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
     95       pipe_surface_reference(&softpipe->framebuffer.cbufs[i], NULL);
     96    }
     97 
     98    sp_destroy_tile_cache(softpipe->zsbuf_cache);
     99    pipe_surface_reference(&softpipe->framebuffer.zsbuf, NULL);
    100 
    101    for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) {
    102       for (i = 0; i < ARRAY_SIZE(softpipe->tex_cache[0]); i++) {
    103          sp_destroy_tex_tile_cache(softpipe->tex_cache[sh][i]);
    104          pipe_sampler_view_reference(&softpipe->sampler_views[sh][i], NULL);
    105       }
    106    }
    107 
    108    for (sh = 0; sh < ARRAY_SIZE(softpipe->constants); sh++) {
    109       for (i = 0; i < ARRAY_SIZE(softpipe->constants[0]); i++) {
    110          if (softpipe->constants[sh][i]) {
    111             pipe_resource_reference(&softpipe->constants[sh][i], NULL);
    112          }
    113       }
    114    }
    115 
    116    for (i = 0; i < softpipe->num_vertex_buffers; i++) {
    117       pipe_vertex_buffer_unreference(&softpipe->vertex_buffer[i]);
    118    }
    119 
    120    tgsi_exec_machine_destroy(softpipe->fs_machine);
    121 
    122    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
    123       FREE(softpipe->tgsi.sampler[i]);
    124       FREE(softpipe->tgsi.image[i]);
    125       FREE(softpipe->tgsi.buffer[i]);
    126    }
    127 
    128    FREE( softpipe );
    129 }
    130 
    131 
    132 /**
    133  * if (the texture is being used as a framebuffer surface)
    134  *    return SP_REFERENCED_FOR_WRITE
    135  * else if (the texture is a bound texture source)
    136  *    return SP_REFERENCED_FOR_READ
    137  * else
    138  *    return SP_UNREFERENCED
    139  */
    140 unsigned int
    141 softpipe_is_resource_referenced( struct pipe_context *pipe,
    142                                  struct pipe_resource *texture,
    143                                  unsigned level, int layer)
    144 {
    145    struct softpipe_context *softpipe = softpipe_context( pipe );
    146    unsigned i, sh;
    147 
    148    if (texture->target == PIPE_BUFFER)
    149       return SP_UNREFERENCED;
    150 
    151    /* check if any of the bound drawing surfaces are this texture */
    152    if (softpipe->dirty_render_cache) {
    153       for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
    154          if (softpipe->framebuffer.cbufs[i] &&
    155              softpipe->framebuffer.cbufs[i]->texture == texture) {
    156             return SP_REFERENCED_FOR_WRITE;
    157          }
    158       }
    159       if (softpipe->framebuffer.zsbuf &&
    160           softpipe->framebuffer.zsbuf->texture == texture) {
    161          return SP_REFERENCED_FOR_WRITE;
    162       }
    163    }
    164 
    165    /* check if any of the tex_cache textures are this texture */
    166    for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) {
    167       for (i = 0; i < ARRAY_SIZE(softpipe->tex_cache[0]); i++) {
    168          if (softpipe->tex_cache[sh][i] &&
    169              softpipe->tex_cache[sh][i]->texture == texture)
    170             return SP_REFERENCED_FOR_READ;
    171       }
    172    }
    173 
    174    return SP_UNREFERENCED;
    175 }
    176 
    177 
    178 
    179 
    180 static void
    181 softpipe_render_condition(struct pipe_context *pipe,
    182                           struct pipe_query *query,
    183                           boolean condition,
    184                           enum pipe_render_cond_flag mode)
    185 {
    186    struct softpipe_context *softpipe = softpipe_context( pipe );
    187 
    188    softpipe->render_cond_query = query;
    189    softpipe->render_cond_mode = mode;
    190    softpipe->render_cond_cond = condition;
    191 }
    192 
    193 
    194 
    195 struct pipe_context *
    196 softpipe_create_context(struct pipe_screen *screen,
    197 			void *priv, unsigned flags)
    198 {
    199    struct softpipe_screen *sp_screen = softpipe_screen(screen);
    200    struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
    201    uint i, sh;
    202 
    203    util_init_math();
    204 
    205    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
    206       softpipe->tgsi.sampler[i] = sp_create_tgsi_sampler();
    207    }
    208 
    209    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
    210       softpipe->tgsi.image[i] = sp_create_tgsi_image();
    211    }
    212 
    213    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
    214       softpipe->tgsi.buffer[i] = sp_create_tgsi_buffer();
    215    }
    216 
    217    softpipe->dump_fs = debug_get_bool_option( "SOFTPIPE_DUMP_FS", FALSE );
    218    softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE );
    219    softpipe->dump_cs = debug_get_bool_option( "SOFTPIPE_DUMP_CS", FALSE );
    220 
    221    softpipe->pipe.screen = screen;
    222    softpipe->pipe.destroy = softpipe_destroy;
    223    softpipe->pipe.priv = priv;
    224 
    225    /* state setters */
    226    softpipe_init_blend_funcs(&softpipe->pipe);
    227    softpipe_init_clip_funcs(&softpipe->pipe);
    228    softpipe_init_query_funcs( softpipe );
    229    softpipe_init_rasterizer_funcs(&softpipe->pipe);
    230    softpipe_init_sampler_funcs(&softpipe->pipe);
    231    softpipe_init_shader_funcs(&softpipe->pipe);
    232    softpipe_init_streamout_funcs(&softpipe->pipe);
    233    softpipe_init_texture_funcs( &softpipe->pipe );
    234    softpipe_init_vertex_funcs(&softpipe->pipe);
    235    softpipe_init_image_funcs(&softpipe->pipe);
    236 
    237    softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
    238 
    239    softpipe->pipe.draw_vbo = softpipe_draw_vbo;
    240 
    241    softpipe->pipe.launch_grid = softpipe_launch_grid;
    242 
    243    softpipe->pipe.clear = softpipe_clear;
    244    softpipe->pipe.flush = softpipe_flush_wrapped;
    245    softpipe->pipe.texture_barrier = softpipe_texture_barrier;
    246    softpipe->pipe.memory_barrier = softpipe_memory_barrier;
    247    softpipe->pipe.render_condition = softpipe_render_condition;
    248 
    249    /*
    250     * Alloc caches for accessing drawing surfaces and textures.
    251     * Must be before quad stage setup!
    252     */
    253    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
    254       softpipe->cbuf_cache[i] = sp_create_tile_cache( &softpipe->pipe );
    255    softpipe->zsbuf_cache = sp_create_tile_cache( &softpipe->pipe );
    256 
    257    /* Allocate texture caches */
    258    for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) {
    259       for (i = 0; i < ARRAY_SIZE(softpipe->tex_cache[0]); i++) {
    260          softpipe->tex_cache[sh][i] = sp_create_tex_tile_cache(&softpipe->pipe);
    261          if (!softpipe->tex_cache[sh][i])
    262             goto fail;
    263       }
    264    }
    265 
    266    softpipe->fs_machine = tgsi_exec_machine_create(PIPE_SHADER_FRAGMENT);
    267 
    268    /* setup quad rendering stages */
    269    softpipe->quad.shade = sp_quad_shade_stage(softpipe);
    270    softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
    271    softpipe->quad.blend = sp_quad_blend_stage(softpipe);
    272    softpipe->quad.pstipple = sp_quad_polygon_stipple_stage(softpipe);
    273 
    274    softpipe->pipe.stream_uploader = u_upload_create_default(&softpipe->pipe);
    275    if (!softpipe->pipe.stream_uploader)
    276       goto fail;
    277    softpipe->pipe.const_uploader = softpipe->pipe.stream_uploader;
    278 
    279    /*
    280     * Create drawing context and plug our rendering stage into it.
    281     */
    282    if (sp_screen->use_llvm)
    283       softpipe->draw = draw_create(&softpipe->pipe);
    284    else
    285       softpipe->draw = draw_create_no_llvm(&softpipe->pipe);
    286    if (!softpipe->draw)
    287       goto fail;
    288 
    289    draw_texture_sampler(softpipe->draw,
    290                         PIPE_SHADER_VERTEX,
    291                         (struct tgsi_sampler *)
    292                            softpipe->tgsi.sampler[PIPE_SHADER_VERTEX]);
    293 
    294    draw_texture_sampler(softpipe->draw,
    295                         PIPE_SHADER_GEOMETRY,
    296                         (struct tgsi_sampler *)
    297                            softpipe->tgsi.sampler[PIPE_SHADER_GEOMETRY]);
    298 
    299    draw_image(softpipe->draw,
    300               PIPE_SHADER_VERTEX,
    301               (struct tgsi_image *)
    302               softpipe->tgsi.image[PIPE_SHADER_VERTEX]);
    303 
    304    draw_image(softpipe->draw,
    305               PIPE_SHADER_GEOMETRY,
    306               (struct tgsi_image *)
    307               softpipe->tgsi.image[PIPE_SHADER_GEOMETRY]);
    308 
    309    draw_buffer(softpipe->draw,
    310               PIPE_SHADER_VERTEX,
    311               (struct tgsi_buffer *)
    312               softpipe->tgsi.buffer[PIPE_SHADER_VERTEX]);
    313 
    314    draw_buffer(softpipe->draw,
    315               PIPE_SHADER_GEOMETRY,
    316               (struct tgsi_buffer *)
    317               softpipe->tgsi.buffer[PIPE_SHADER_GEOMETRY]);
    318 
    319    if (debug_get_bool_option( "SOFTPIPE_NO_RAST", FALSE ))
    320       softpipe->no_rast = TRUE;
    321 
    322    softpipe->vbuf_backend = sp_create_vbuf_backend(softpipe);
    323    if (!softpipe->vbuf_backend)
    324       goto fail;
    325 
    326    softpipe->vbuf = draw_vbuf_stage(softpipe->draw, softpipe->vbuf_backend);
    327    if (!softpipe->vbuf)
    328       goto fail;
    329 
    330    draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf);
    331    draw_set_render(softpipe->draw, softpipe->vbuf_backend);
    332 
    333    softpipe->blitter = util_blitter_create(&softpipe->pipe);
    334    if (!softpipe->blitter) {
    335       goto fail;
    336    }
    337 
    338    /* must be done before installing Draw stages */
    339    util_blitter_cache_all_shaders(softpipe->blitter);
    340 
    341    /* plug in AA line/point stages */
    342    draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
    343    draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
    344 
    345    /* Do polygon stipple w/ texture map + frag prog? */
    346 #if DO_PSTIPPLE_IN_DRAW_MODULE
    347    draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);
    348 #endif
    349 
    350    draw_wide_point_sprites(softpipe->draw, TRUE);
    351 
    352    sp_init_surface_functions(softpipe);
    353 
    354 #if DO_PSTIPPLE_IN_HELPER_MODULE
    355    /* create the polgon stipple sampler */
    356    softpipe->pstipple.sampler = util_pstipple_create_sampler(&softpipe->pipe);
    357 #endif
    358 
    359    return &softpipe->pipe;
    360 
    361  fail:
    362    softpipe_destroy(&softpipe->pipe);
    363    return NULL;
    364 }
    365