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 #include "svga_winsys.h"
     47 
     48 #define CONST0_UPLOAD_DEFAULT_SIZE 65536
     49 
     50 DEBUG_GET_ONCE_BOOL_OPTION(no_swtnl, "SVGA_NO_SWTNL", FALSE)
     51 DEBUG_GET_ONCE_BOOL_OPTION(force_swtnl, "SVGA_FORCE_SWTNL", FALSE);
     52 DEBUG_GET_ONCE_BOOL_OPTION(use_min_mipmap, "SVGA_USE_MIN_MIPMAP", FALSE);
     53 DEBUG_GET_ONCE_BOOL_OPTION(no_line_width, "SVGA_NO_LINE_WIDTH", FALSE);
     54 DEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE", FALSE);
     55 
     56 
     57 static void
     58 svga_destroy(struct pipe_context *pipe)
     59 {
     60    struct svga_context *svga = svga_context(pipe);
     61    unsigned shader, i;
     62 
     63    /* free any alternate rasterizer states used for point sprite */
     64    for (i = 0; i < ARRAY_SIZE(svga->rasterizer_no_cull); i++) {
     65       if (svga->rasterizer_no_cull[i]) {
     66          pipe->delete_rasterizer_state(pipe, svga->rasterizer_no_cull[i]);
     67       }
     68    }
     69 
     70    /* free HW constant buffers */
     71    for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) {
     72       pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], NULL);
     73    }
     74 
     75    pipe->delete_blend_state(pipe, svga->noop_blend);
     76 
     77    /* free query gb object */
     78    if (svga->gb_query) {
     79       pipe->destroy_query(pipe, NULL);
     80       svga->gb_query = NULL;
     81    }
     82 
     83    util_blitter_destroy(svga->blitter);
     84 
     85    svga_cleanup_sampler_state(svga);
     86    svga_cleanup_framebuffer(svga);
     87    svga_cleanup_tss_binding(svga);
     88    svga_cleanup_vertex_state(svga);
     89 
     90    svga_destroy_swtnl(svga);
     91    svga_hwtnl_destroy(svga->hwtnl);
     92 
     93    svga->swc->destroy(svga->swc);
     94 
     95    util_bitmask_destroy(svga->blend_object_id_bm);
     96    util_bitmask_destroy(svga->ds_object_id_bm);
     97    util_bitmask_destroy(svga->input_element_object_id_bm);
     98    util_bitmask_destroy(svga->rast_object_id_bm);
     99    util_bitmask_destroy(svga->sampler_object_id_bm);
    100    util_bitmask_destroy(svga->sampler_view_id_bm);
    101    util_bitmask_destroy(svga->shader_id_bm);
    102    util_bitmask_destroy(svga->surface_view_id_bm);
    103    util_bitmask_destroy(svga->stream_output_id_bm);
    104    util_bitmask_destroy(svga->query_id_bm);
    105    u_upload_destroy(svga->const0_upload);
    106    svga_texture_transfer_map_upload_destroy(svga);
    107 
    108    /* free user's constant buffers */
    109    for (shader = 0; shader < PIPE_SHADER_TYPES; ++shader) {
    110       for (i = 0; i < ARRAY_SIZE(svga->curr.constbufs[shader]); ++i) {
    111          pipe_resource_reference(&svga->curr.constbufs[shader][i].buffer, NULL);
    112       }
    113    }
    114 
    115    FREE(svga);
    116 }
    117 
    118 
    119 struct pipe_context *
    120 svga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
    121 {
    122    struct svga_screen *svgascreen = svga_screen(screen);
    123    struct svga_context *svga = NULL;
    124    enum pipe_error ret;
    125 
    126    svga = CALLOC_STRUCT(svga_context);
    127    if (!svga)
    128       goto cleanup;
    129 
    130    LIST_INITHEAD(&svga->dirty_buffers);
    131 
    132    svga->pipe.screen = screen;
    133    svga->pipe.priv = priv;
    134    svga->pipe.destroy = svga_destroy;
    135 
    136    svga->swc = svgascreen->sws->context_create(svgascreen->sws);
    137    if (!svga->swc)
    138       goto cleanup;
    139 
    140    svga_init_resource_functions(svga);
    141    svga_init_blend_functions(svga);
    142    svga_init_blit_functions(svga);
    143    svga_init_depth_stencil_functions(svga);
    144    svga_init_draw_functions(svga);
    145    svga_init_flush_functions(svga);
    146    svga_init_misc_functions(svga);
    147    svga_init_rasterizer_functions(svga);
    148    svga_init_sampler_functions(svga);
    149    svga_init_fs_functions(svga);
    150    svga_init_vs_functions(svga);
    151    svga_init_gs_functions(svga);
    152    svga_init_vertex_functions(svga);
    153    svga_init_constbuffer_functions(svga);
    154    svga_init_query_functions(svga);
    155    svga_init_surface_functions(svga);
    156    svga_init_stream_output_functions(svga);
    157    svga_init_clear_functions(svga);
    158 
    159    /* init misc state */
    160    svga->curr.sample_mask = ~0;
    161 
    162    /* debug */
    163    svga->debug.no_swtnl = debug_get_option_no_swtnl();
    164    svga->debug.force_swtnl = debug_get_option_force_swtnl();
    165    svga->debug.use_min_mipmap = debug_get_option_use_min_mipmap();
    166    svga->debug.no_line_width = debug_get_option_no_line_width();
    167    svga->debug.force_hw_line_stipple = debug_get_option_force_hw_line_stipple();
    168 
    169    if (!(svga->blend_object_id_bm = util_bitmask_create()))
    170       goto cleanup;
    171 
    172    if (!(svga->ds_object_id_bm = util_bitmask_create()))
    173       goto cleanup;
    174 
    175    if (!(svga->input_element_object_id_bm = util_bitmask_create()))
    176       goto cleanup;
    177 
    178    if (!(svga->rast_object_id_bm = util_bitmask_create()))
    179       goto cleanup;
    180 
    181    if (!(svga->sampler_object_id_bm = util_bitmask_create()))
    182       goto cleanup;
    183 
    184    if (!(svga->sampler_view_id_bm = util_bitmask_create()))
    185       goto cleanup;
    186 
    187    if (!(svga->shader_id_bm = util_bitmask_create()))
    188       goto cleanup;
    189 
    190    if (!(svga->surface_view_id_bm = util_bitmask_create()))
    191       goto cleanup;
    192 
    193    if (!(svga->stream_output_id_bm = util_bitmask_create()))
    194       goto cleanup;
    195 
    196    if (!(svga->query_id_bm = util_bitmask_create()))
    197       goto cleanup;
    198 
    199    svga->hwtnl = svga_hwtnl_create(svga);
    200    if (svga->hwtnl == NULL)
    201       goto cleanup;
    202 
    203    if (!svga_init_swtnl(svga))
    204       goto cleanup;
    205 
    206    ret = svga_emit_initial_state(svga);
    207    if (ret != PIPE_OK)
    208       goto cleanup;
    209 
    210    svga->const0_upload = u_upload_create(&svga->pipe,
    211                                          CONST0_UPLOAD_DEFAULT_SIZE,
    212                                          PIPE_BIND_CONSTANT_BUFFER,
    213                                          PIPE_USAGE_STREAM);
    214    if (!svga->const0_upload)
    215       goto cleanup;
    216 
    217    if (!svga_texture_transfer_map_upload_create(svga))
    218       goto cleanup;
    219 
    220    /* Avoid shortcircuiting state with initial value of zero.
    221     */
    222    memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear));
    223    memset(&svga->state.hw_clear.framebuffer, 0x0,
    224           sizeof(svga->state.hw_clear.framebuffer));
    225 
    226    memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw));
    227    memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views));
    228    memset(&svga->state.hw_draw.num_samplers, 0,
    229       sizeof(svga->state.hw_draw.num_samplers));
    230    memset(&svga->state.hw_draw.num_sampler_views, 0,
    231       sizeof(svga->state.hw_draw.num_sampler_views));
    232    memset(svga->state.hw_draw.sampler_views, 0,
    233           sizeof(svga->state.hw_draw.sampler_views));
    234    svga->state.hw_draw.num_views = 0;
    235    svga->state.hw_draw.num_rendertargets = 0;
    236    svga->state.hw_draw.dsv = NULL;
    237 
    238    /* Initialize the shader pointers */
    239    svga->state.hw_draw.vs = NULL;
    240    svga->state.hw_draw.gs = NULL;
    241    svga->state.hw_draw.fs = NULL;
    242 
    243    /* Initialize the currently bound buffer resources */
    244    memset(svga->state.hw_draw.constbuf, 0,
    245           sizeof(svga->state.hw_draw.constbuf));
    246    memset(svga->state.hw_draw.default_constbuf_size, 0,
    247           sizeof(svga->state.hw_draw.default_constbuf_size));
    248    memset(svga->state.hw_draw.enabled_constbufs, 0,
    249           sizeof(svga->state.hw_draw.enabled_constbufs));
    250    svga->state.hw_draw.ib = NULL;
    251    svga->state.hw_draw.num_vbuffers = 0;
    252    memset(svga->state.hw_draw.vbuffers, 0,
    253           sizeof(svga->state.hw_draw.vbuffers));
    254    svga->state.hw_draw.const0_buffer = NULL;
    255    svga->state.hw_draw.const0_handle = NULL;
    256 
    257    /* Create a no-operation blend state which we will bind whenever the
    258     * requested blend state is impossible (e.g. due to having an integer
    259     * render target attached).
    260     *
    261     * XXX: We will probably actually need 16 of these, one for each possible
    262     * RGBA color mask (4 bits).  Then, we would bind the one with a color mask
    263     * matching the blend state it is replacing.
    264     */
    265    {
    266       struct pipe_blend_state noop_tmpl = {0};
    267       unsigned i;
    268 
    269       for (i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
    270          // Set the color mask to all-ones.  Later this may change.
    271          noop_tmpl.rt[i].colormask = PIPE_MASK_RGBA;
    272       }
    273       svga->noop_blend = svga->pipe.create_blend_state(&svga->pipe, &noop_tmpl);
    274    }
    275 
    276    svga->dirty = ~0;
    277    svga->pred.query_id = SVGA3D_INVALID_ID;
    278 
    279    return &svga->pipe;
    280 
    281 cleanup:
    282    svga_destroy_swtnl(svga);
    283 
    284    if (svga->const0_upload)
    285       u_upload_destroy(svga->const0_upload);
    286    svga_texture_transfer_map_upload_destroy(svga);
    287    if (svga->hwtnl)
    288       svga_hwtnl_destroy(svga->hwtnl);
    289    if (svga->swc)
    290       svga->swc->destroy(svga->swc);
    291    util_bitmask_destroy(svga->blend_object_id_bm);
    292    util_bitmask_destroy(svga->ds_object_id_bm);
    293    util_bitmask_destroy(svga->input_element_object_id_bm);
    294    util_bitmask_destroy(svga->rast_object_id_bm);
    295    util_bitmask_destroy(svga->sampler_object_id_bm);
    296    util_bitmask_destroy(svga->sampler_view_id_bm);
    297    util_bitmask_destroy(svga->shader_id_bm);
    298    util_bitmask_destroy(svga->surface_view_id_bm);
    299    util_bitmask_destroy(svga->stream_output_id_bm);
    300    util_bitmask_destroy(svga->query_id_bm);
    301    FREE(svga);
    302    return NULL;
    303 }
    304 
    305 
    306 void
    307 svga_context_flush(struct svga_context *svga,
    308                    struct pipe_fence_handle **pfence)
    309 {
    310    struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
    311    struct pipe_fence_handle *fence = NULL;
    312    uint64_t t0;
    313 
    314    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFLUSH);
    315 
    316    svga->curr.nr_fbs = 0;
    317 
    318    /* Unmap the 0th/default constant buffer.  The u_upload_unmap() function
    319     * will call pipe_context::transfer_flush_region() to indicate the
    320     * region of the buffer which was modified (and needs to be uploaded).
    321     */
    322    if (svga->state.hw_draw.const0_handle) {
    323       assert(svga->state.hw_draw.const0_buffer);
    324       u_upload_unmap(svga->const0_upload);
    325       pipe_resource_reference(&svga->state.hw_draw.const0_buffer, NULL);
    326       svga->state.hw_draw.const0_handle = NULL;
    327    }
    328 
    329    /* Ensure that texture dma uploads are processed
    330     * before submitting commands.
    331     */
    332    svga_context_flush_buffers(svga);
    333 
    334    svga->hud.command_buffer_size +=
    335       svga->swc->get_command_buffer_size(svga->swc);
    336 
    337    /* Flush pending commands to hardware:
    338     */
    339    t0 = svga_get_time(svga);
    340    svga->swc->flush(svga->swc, &fence);
    341    svga->hud.flush_time += (svga_get_time(svga) - t0);
    342 
    343    svga->hud.num_flushes++;
    344 
    345    svga_screen_cache_flush(svgascreen, fence);
    346 
    347    SVGA3D_ResetLastCommand(svga->swc);
    348 
    349    /* To force the re-emission of rendertargets and texture sampler bindings on
    350     * the next command buffer.
    351     */
    352    svga->rebind.flags.rendertargets = TRUE;
    353    svga->rebind.flags.texture_samplers = TRUE;
    354 
    355    if (svga_have_gb_objects(svga)) {
    356 
    357       svga->rebind.flags.constbufs = TRUE;
    358       svga->rebind.flags.vs = TRUE;
    359       svga->rebind.flags.fs = TRUE;
    360       svga->rebind.flags.gs = TRUE;
    361 
    362       if (svga_need_to_rebind_resources(svga)) {
    363          svga->rebind.flags.query = TRUE;
    364       }
    365    }
    366 
    367    if (SVGA_DEBUG & DEBUG_SYNC) {
    368       if (fence)
    369          svga->pipe.screen->fence_finish(svga->pipe.screen, NULL, fence,
    370                                           PIPE_TIMEOUT_INFINITE);
    371    }
    372 
    373    if (pfence)
    374       svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence);
    375 
    376    svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
    377 
    378    SVGA_STATS_TIME_POP(svga_sws(svga));
    379 }
    380 
    381 
    382 /**
    383  * Flush pending commands and wait for completion with a fence.
    384  */
    385 void
    386 svga_context_finish(struct svga_context *svga)
    387 {
    388    struct pipe_screen *screen = svga->pipe.screen;
    389    struct pipe_fence_handle *fence = NULL;
    390 
    391    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFINISH);
    392 
    393    svga_context_flush(svga, &fence);
    394    screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
    395    screen->fence_reference(screen, &fence, NULL);
    396 
    397    SVGA_STATS_TIME_POP(svga_sws(svga));
    398 }
    399 
    400 
    401 /**
    402  * Emit pending drawing commands to the command buffer.
    403  * If the command buffer overflows, we flush it and retry.
    404  * \sa svga_hwtnl_flush()
    405  */
    406 void
    407 svga_hwtnl_flush_retry(struct svga_context *svga)
    408 {
    409    enum pipe_error ret = PIPE_OK;
    410 
    411    ret = svga_hwtnl_flush(svga->hwtnl);
    412    if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
    413       svga_context_flush(svga, NULL);
    414       ret = svga_hwtnl_flush(svga->hwtnl);
    415    }
    416 
    417    assert(ret == PIPE_OK);
    418 }
    419 
    420 
    421 /**
    422  * Flush the primitive queue if this buffer is referred.
    423  *
    424  * Otherwise DMA commands on the referred buffer will be emitted too late.
    425  */
    426 void
    427 svga_hwtnl_flush_buffer(struct svga_context *svga,
    428                         struct pipe_resource *buffer)
    429 {
    430    if (svga_hwtnl_is_buffer_referred(svga->hwtnl, buffer)) {
    431       svga_hwtnl_flush_retry(svga);
    432    }
    433 }
    434 
    435 
    436 /**
    437  * Emit all operations pending on host surfaces.
    438  */
    439 void
    440 svga_surfaces_flush(struct svga_context *svga)
    441 {
    442    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SURFACEFLUSH);
    443 
    444    /* Emit buffered drawing commands.
    445     */
    446    svga_hwtnl_flush_retry(svga);
    447 
    448    /* Emit back-copy from render target views to textures.
    449     */
    450    svga_propagate_rendertargets(svga);
    451 
    452    SVGA_STATS_TIME_POP(svga_sws(svga));
    453 }
    454 
    455 
    456 struct svga_winsys_context *
    457 svga_winsys_context(struct pipe_context *pipe)
    458 {
    459    return svga_context(pipe)->swc;
    460 }
    461