Home | History | Annotate | Download | only in ilo
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 2012-2013 LunarG, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Chia-I Wu <olv (at) lunarg.com>
     26  */
     27 
     28 #include "util/u_upload_mgr.h"
     29 
     30 #include "ilo_blit.h"
     31 #include "ilo_blitter.h"
     32 #include "ilo_cp.h"
     33 #include "ilo_draw.h"
     34 #include "ilo_gpgpu.h"
     35 #include "ilo_query.h"
     36 #include "ilo_render.h"
     37 #include "ilo_resource.h"
     38 #include "ilo_screen.h"
     39 #include "ilo_shader.h"
     40 #include "ilo_state.h"
     41 #include "ilo_transfer.h"
     42 #include "ilo_video.h"
     43 #include "ilo_context.h"
     44 
     45 static void
     46 ilo_context_cp_submitted(struct ilo_cp *cp, void *data)
     47 {
     48    struct ilo_context *ilo = ilo_context(data);
     49 
     50    /* builder buffers are reallocated */
     51    ilo_render_invalidate_builder(ilo->render);
     52 }
     53 
     54 static void
     55 ilo_flush(struct pipe_context *pipe,
     56           struct pipe_fence_handle **f,
     57           unsigned flags)
     58 {
     59    struct ilo_context *ilo = ilo_context(pipe);
     60 
     61    ilo_cp_submit(ilo->cp,
     62          (flags & PIPE_FLUSH_END_OF_FRAME) ? "frame end" : "user request");
     63 
     64    if (f) {
     65       struct pipe_screen *screen = pipe->screen;
     66       screen->fence_reference(screen, f, NULL);
     67       *f = ilo_screen_fence_create(pipe->screen, ilo->cp->last_submitted_bo);
     68    }
     69 }
     70 
     71 static void
     72 ilo_render_condition(struct pipe_context *pipe,
     73                      struct pipe_query *query,
     74                      boolean condition,
     75                      uint mode)
     76 {
     77    struct ilo_context *ilo = ilo_context(pipe);
     78 
     79    /* reference count? */
     80    ilo->render_condition.query = query;
     81    ilo->render_condition.condition = condition;
     82    ilo->render_condition.mode = mode;
     83 }
     84 
     85 bool
     86 ilo_skip_rendering(struct ilo_context *ilo)
     87 {
     88    uint64_t result;
     89    bool wait;
     90 
     91    if (!ilo->render_condition.query)
     92       return false;
     93 
     94    switch (ilo->render_condition.mode) {
     95    case PIPE_RENDER_COND_WAIT:
     96    case PIPE_RENDER_COND_BY_REGION_WAIT:
     97       wait = true;
     98       break;
     99    case PIPE_RENDER_COND_NO_WAIT:
    100    case PIPE_RENDER_COND_BY_REGION_NO_WAIT:
    101    default:
    102       wait = false;
    103       break;
    104    }
    105 
    106    if (ilo->base.get_query_result(&ilo->base, ilo->render_condition.query,
    107             wait, (union pipe_query_result *) &result))
    108       return ((bool) result == ilo->render_condition.condition);
    109    else
    110       return false;
    111 }
    112 
    113 static void
    114 ilo_context_destroy(struct pipe_context *pipe)
    115 {
    116    struct ilo_context *ilo = ilo_context(pipe);
    117 
    118    ilo_state_vector_cleanup(&ilo->state_vector);
    119 
    120    if (ilo->uploader)
    121       u_upload_destroy(ilo->uploader);
    122 
    123    if (ilo->blitter)
    124       ilo_blitter_destroy(ilo->blitter);
    125    if (ilo->render)
    126       ilo_render_destroy(ilo->render);
    127    if (ilo->shader_cache)
    128       ilo_shader_cache_destroy(ilo->shader_cache);
    129    if (ilo->cp)
    130       ilo_cp_destroy(ilo->cp);
    131 
    132    slab_destroy(&ilo->transfer_mempool);
    133 
    134    FREE(ilo);
    135 }
    136 
    137 static struct pipe_context *
    138 ilo_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
    139 {
    140    struct ilo_screen *is = ilo_screen(screen);
    141    struct ilo_context *ilo;
    142 
    143    ilo = CALLOC_STRUCT(ilo_context);
    144    if (!ilo)
    145       return NULL;
    146 
    147    ilo->winsys = is->dev.winsys;
    148    ilo->dev = &is->dev;
    149 
    150    /*
    151     * initialize first, otherwise it may not be safe to call
    152     * ilo_context_destroy() on errors
    153     */
    154    slab_create(&ilo->transfer_mempool,
    155          sizeof(struct ilo_transfer), 64);
    156 
    157    ilo->shader_cache = ilo_shader_cache_create();
    158    ilo->cp = ilo_cp_create(ilo->dev, ilo->winsys, ilo->shader_cache);
    159    if (ilo->cp)
    160       ilo->render = ilo_render_create(&ilo->cp->builder);
    161 
    162    if (!ilo->cp || !ilo->shader_cache || !ilo->render) {
    163       ilo_context_destroy(&ilo->base);
    164       return NULL;
    165    }
    166 
    167    ilo_cp_set_submit_callback(ilo->cp,
    168          ilo_context_cp_submitted, (void *) ilo);
    169 
    170    ilo->base.screen = screen;
    171    ilo->base.priv = priv;
    172 
    173    ilo->base.destroy = ilo_context_destroy;
    174    ilo->base.flush = ilo_flush;
    175    ilo->base.render_condition = ilo_render_condition;
    176 
    177    ilo_init_draw_functions(ilo);
    178    ilo_init_query_functions(ilo);
    179    ilo_init_state_functions(ilo);
    180    ilo_init_blit_functions(ilo);
    181    ilo_init_transfer_functions(ilo);
    182    ilo_init_video_functions(ilo);
    183    ilo_init_gpgpu_functions(ilo);
    184 
    185    ilo_init_draw(ilo);
    186    ilo_state_vector_init(ilo->dev, &ilo->state_vector);
    187 
    188    /*
    189     * These must be called last as u_upload/u_blitter are clients of the pipe
    190     * context.
    191     */
    192    ilo->uploader = u_upload_create(&ilo->base, 1024 * 1024,
    193          PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_INDEX_BUFFER,
    194                                    PIPE_USAGE_STREAM);
    195    if (!ilo->uploader) {
    196       ilo_context_destroy(&ilo->base);
    197       return NULL;
    198    }
    199 
    200    ilo->blitter = ilo_blitter_create(ilo);
    201    if (!ilo->blitter) {
    202       ilo_context_destroy(&ilo->base);
    203       return NULL;
    204    }
    205 
    206    return &ilo->base;
    207 }
    208 
    209 /**
    210  * Initialize context-related functions.
    211  */
    212 void
    213 ilo_init_context_functions(struct ilo_screen *is)
    214 {
    215    is->base.context_create = ilo_context_create;
    216 }
    217