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 "svga_cmd.h"
     27 
     28 #include "pipe/p_defines.h"
     29 #include "util/u_inlines.h"
     30 #include "pipe/p_screen.h"
     31 #include "util/u_memory.h"
     32 #include "util/u_bitmask.h"
     33 #include "util/u_upload_mgr.h"
     34 
     35 #include "svga_context.h"
     36 #include "svga_screen.h"
     37 #include "svga_surface.h"
     38 #include "svga_resource_texture.h"
     39 #include "svga_resource_buffer.h"
     40 #include "svga_resource.h"
     41 #include "svga_winsys.h"
     42 #include "svga_swtnl.h"
     43 #include "svga_draw.h"
     44 #include "svga_debug.h"
     45 #include "svga_state.h"
     46 
     47 DEBUG_GET_ONCE_BOOL_OPTION(no_swtnl, "SVGA_NO_SWTNL", FALSE)
     48 DEBUG_GET_ONCE_BOOL_OPTION(force_swtnl, "SVGA_FORCE_SWTNL", FALSE);
     49 DEBUG_GET_ONCE_BOOL_OPTION(use_min_mipmap, "SVGA_USE_MIN_MIPMAP", FALSE);
     50 DEBUG_GET_ONCE_NUM_OPTION(disable_shader, "SVGA_DISABLE_SHADER", ~0);
     51 DEBUG_GET_ONCE_BOOL_OPTION(no_line_width, "SVGA_NO_LINE_WIDTH", FALSE);
     52 DEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE", FALSE);
     53 
     54 static void svga_destroy( struct pipe_context *pipe )
     55 {
     56    struct svga_context *svga = svga_context( pipe );
     57    unsigned shader;
     58 
     59    svga_cleanup_framebuffer( svga );
     60    svga_cleanup_tss_binding( svga );
     61 
     62    svga_hwtnl_destroy( svga->hwtnl );
     63 
     64    svga_cleanup_vertex_state(svga);
     65 
     66    svga->swc->destroy(svga->swc);
     67 
     68    svga_destroy_swtnl( svga );
     69 
     70    u_upload_destroy( svga->upload_vb );
     71    u_upload_destroy( svga->upload_ib );
     72 
     73    util_bitmask_destroy( svga->vs_bm );
     74    util_bitmask_destroy( svga->fs_bm );
     75 
     76    for(shader = 0; shader < PIPE_SHADER_TYPES; ++shader)
     77       pipe_resource_reference( &svga->curr.cb[shader], NULL );
     78 
     79    FREE( svga );
     80 }
     81 
     82 
     83 
     84 struct pipe_context *svga_context_create( struct pipe_screen *screen,
     85 					  void *priv )
     86 {
     87    struct svga_screen *svgascreen = svga_screen(screen);
     88    struct svga_context *svga = NULL;
     89    enum pipe_error ret;
     90 
     91    svga = CALLOC_STRUCT(svga_context);
     92    if (svga == NULL)
     93       goto no_svga;
     94 
     95    svga->pipe.screen = screen;
     96    svga->pipe.priv = priv;
     97    svga->pipe.destroy = svga_destroy;
     98    svga->pipe.clear = svga_clear;
     99 
    100    svga->swc = svgascreen->sws->context_create(svgascreen->sws);
    101    if(!svga->swc)
    102       goto no_swc;
    103 
    104    svga_init_resource_functions(svga);
    105    svga_init_blend_functions(svga);
    106    svga_init_blit_functions(svga);
    107    svga_init_depth_stencil_functions(svga);
    108    svga_init_draw_functions(svga);
    109    svga_init_flush_functions(svga);
    110    svga_init_misc_functions(svga);
    111    svga_init_rasterizer_functions(svga);
    112    svga_init_sampler_functions(svga);
    113    svga_init_fs_functions(svga);
    114    svga_init_vs_functions(svga);
    115    svga_init_vertex_functions(svga);
    116    svga_init_constbuffer_functions(svga);
    117    svga_init_query_functions(svga);
    118    svga_init_surface_functions(svga);
    119 
    120 
    121    /* debug */
    122    svga->debug.no_swtnl = debug_get_option_no_swtnl();
    123    svga->debug.force_swtnl = debug_get_option_force_swtnl();
    124    svga->debug.use_min_mipmap = debug_get_option_use_min_mipmap();
    125    svga->debug.disable_shader = debug_get_option_disable_shader();
    126    svga->debug.no_line_width = debug_get_option_no_line_width();
    127    svga->debug.force_hw_line_stipple = debug_get_option_force_hw_line_stipple();
    128 
    129    svga->fs_bm = util_bitmask_create();
    130    if (svga->fs_bm == NULL)
    131       goto no_fs_bm;
    132 
    133    svga->vs_bm = util_bitmask_create();
    134    if (svga->vs_bm == NULL)
    135       goto no_vs_bm;
    136 
    137    svga->upload_ib = u_upload_create( &svga->pipe,
    138                                       32 * 1024,
    139                                       16,
    140                                       PIPE_BIND_INDEX_BUFFER );
    141    if (svga->upload_ib == NULL)
    142       goto no_upload_ib;
    143 
    144    svga->upload_vb = u_upload_create( &svga->pipe,
    145                                       128 * 1024,
    146                                       16,
    147                                       PIPE_BIND_VERTEX_BUFFER );
    148    if (svga->upload_vb == NULL)
    149       goto no_upload_vb;
    150 
    151    svga->hwtnl = svga_hwtnl_create( svga,
    152                                     svga->upload_ib,
    153                                     svga->swc );
    154    if (svga->hwtnl == NULL)
    155       goto no_hwtnl;
    156 
    157    if (!svga_init_swtnl(svga))
    158       goto no_swtnl;
    159 
    160    ret = svga_emit_initial_state( svga );
    161    if (ret != PIPE_OK)
    162       goto no_state;
    163 
    164    /* Avoid shortcircuiting state with initial value of zero.
    165     */
    166    memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear));
    167    memset(&svga->state.hw_clear.framebuffer, 0x0,
    168           sizeof(svga->state.hw_clear.framebuffer));
    169 
    170    memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw));
    171    memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views));
    172    svga->state.hw_draw.num_views = 0;
    173 
    174    svga->dirty = ~0;
    175 
    176    LIST_INITHEAD(&svga->dirty_buffers);
    177 
    178    return &svga->pipe;
    179 
    180 no_state:
    181    svga_destroy_swtnl(svga);
    182 no_swtnl:
    183    svga_hwtnl_destroy( svga->hwtnl );
    184 no_hwtnl:
    185    u_upload_destroy( svga->upload_vb );
    186 no_upload_vb:
    187    u_upload_destroy( svga->upload_ib );
    188 no_upload_ib:
    189    util_bitmask_destroy( svga->vs_bm );
    190 no_vs_bm:
    191    util_bitmask_destroy( svga->fs_bm );
    192 no_fs_bm:
    193    svga->swc->destroy(svga->swc);
    194 no_swc:
    195    FREE(svga);
    196 no_svga:
    197    return NULL;
    198 }
    199 
    200 
    201 void svga_context_flush( struct svga_context *svga,
    202                          struct pipe_fence_handle **pfence )
    203 {
    204    struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
    205    struct pipe_fence_handle *fence = NULL;
    206 
    207    svga->curr.nr_fbs = 0;
    208 
    209    /* Flush the upload managers to ensure recycling of upload buffers
    210     * without throttling. This should really be conditioned on
    211     * pipe_buffer_map_range not supporting PIPE_TRANSFER_UNSYNCHRONIZED.
    212     */
    213 
    214    u_upload_flush(svga->upload_vb);
    215    u_upload_flush(svga->upload_ib);
    216 
    217    /* Ensure that texture dma uploads are processed
    218     * before submitting commands.
    219     */
    220    svga_context_flush_buffers(svga);
    221 
    222    /* Flush pending commands to hardware:
    223     */
    224    svga->swc->flush(svga->swc, &fence);
    225 
    226    svga_screen_cache_flush(svgascreen, fence);
    227 
    228    /* To force the re-emission of rendertargets and texture sampler bindings on
    229     * the next command buffer.
    230     */
    231    svga->rebind.rendertargets = TRUE;
    232    svga->rebind.texture_samplers = TRUE;
    233 
    234    if (SVGA_DEBUG & DEBUG_SYNC) {
    235       if (fence)
    236          svga->pipe.screen->fence_finish( svga->pipe.screen, fence,
    237                                           PIPE_TIMEOUT_INFINITE);
    238    }
    239 
    240    if(pfence)
    241       svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence);
    242 
    243    svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
    244 }
    245 
    246 
    247 void svga_hwtnl_flush_retry( struct svga_context *svga )
    248 {
    249    enum pipe_error ret = PIPE_OK;
    250 
    251    ret = svga_hwtnl_flush( svga->hwtnl );
    252    if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
    253       svga_context_flush( svga, NULL );
    254       ret = svga_hwtnl_flush( svga->hwtnl );
    255    }
    256 
    257    assert(ret == 0);
    258 }
    259 
    260 
    261 /**
    262  * Flush the primitive queue if this buffer is referred.
    263  *
    264  * Otherwise DMA commands on the referred buffer will be emitted too late.
    265  */
    266 void svga_hwtnl_flush_buffer( struct svga_context *svga,
    267                               struct pipe_resource *buffer )
    268 {
    269    if (svga_hwtnl_is_buffer_referred(svga->hwtnl, buffer)) {
    270       svga_hwtnl_flush_retry(svga);
    271    }
    272 }
    273 
    274 
    275 /* Emit all operations pending on host surfaces.
    276  */
    277 void svga_surfaces_flush(struct svga_context *svga)
    278 {
    279    unsigned i;
    280 
    281    /* Emit buffered drawing commands.
    282     */
    283    svga_hwtnl_flush_retry( svga );
    284 
    285    /* Emit back-copy from render target view to texture.
    286     */
    287    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
    288       if (svga->curr.framebuffer.cbufs[i])
    289          svga_propagate_surface(svga, svga->curr.framebuffer.cbufs[i]);
    290    }
    291 
    292    if (svga->curr.framebuffer.zsbuf)
    293       svga_propagate_surface(svga, svga->curr.framebuffer.zsbuf);
    294 
    295 }
    296 
    297 
    298 struct svga_winsys_context *
    299 svga_winsys_context( struct pipe_context *pipe )
    300 {
    301    return svga_context( pipe )->swc;
    302 }
    303