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 #ifndef ILO_BLIT_H
     29 #define ILO_BLIT_H
     30 
     31 #include "ilo_common.h"
     32 #include "ilo_context.h"
     33 #include "ilo_state.h"
     34 #include "ilo_resource.h"
     35 
     36 void
     37 ilo_blit_resolve_slices_for_hiz(struct ilo_context *ilo,
     38                                 struct pipe_resource *res, unsigned level,
     39                                 unsigned first_slice, unsigned num_slices,
     40                                 unsigned resolve_flags);
     41 
     42 static inline void
     43 ilo_blit_resolve_slices(struct ilo_context *ilo,
     44                         struct pipe_resource *res, unsigned level,
     45                         unsigned first_slice, unsigned num_slices,
     46                         unsigned resolve_flags)
     47 {
     48    struct ilo_texture *tex;
     49    unsigned slice_mask;
     50 
     51    if (res->target == PIPE_BUFFER)
     52       return;
     53 
     54    tex = ilo_texture(res);
     55 
     56    /*
     57     * This function is called frequently and we need to make it run faster.
     58     * As it is only used to resolve HiZ right now, return early when there is
     59     * no HiZ.
     60     */
     61    if (tex->image.aux.type != ILO_IMAGE_AUX_HIZ ||
     62        !ilo_image_can_enable_aux(&tex->image, level))
     63       return;
     64 
     65    if (tex->image.aux.type == ILO_IMAGE_AUX_HIZ &&
     66        ilo_image_can_enable_aux(&tex->image, level)) {
     67       ilo_blit_resolve_slices_for_hiz(ilo, res, level,
     68             first_slice, num_slices, resolve_flags);
     69    }
     70 
     71    slice_mask =
     72       ILO_TEXTURE_CPU_WRITE |
     73       ILO_TEXTURE_BLT_WRITE |
     74       ILO_TEXTURE_RENDER_WRITE;
     75    /* when there is a new writer, we may need to clear ILO_TEXTURE_CLEAR */
     76    if (resolve_flags & slice_mask)
     77       slice_mask |= ILO_TEXTURE_CLEAR;
     78 
     79    ilo_texture_set_slice_flags(tex, level,
     80          first_slice, num_slices, slice_mask, resolve_flags);
     81 }
     82 
     83 static inline void
     84 ilo_blit_resolve_resource(struct ilo_context *ilo,
     85                           struct pipe_resource *res,
     86                           unsigned resolve_flags)
     87 {
     88    unsigned lv;
     89 
     90    for (lv = 0; lv <= res->last_level; lv++) {
     91       const unsigned num_slices = (res->target == PIPE_TEXTURE_3D) ?
     92          u_minify(res->depth0, lv) : res->array_size;
     93 
     94       ilo_blit_resolve_slices(ilo, res, lv, 0, num_slices, resolve_flags);
     95    }
     96 }
     97 
     98 static inline void
     99 ilo_blit_resolve_surface(struct ilo_context *ilo,
    100                          struct pipe_surface *surf,
    101                          unsigned resolve_flags)
    102 {
    103    if (surf->texture->target == PIPE_BUFFER)
    104       return;
    105 
    106    ilo_blit_resolve_slices(ilo, surf->texture,
    107          surf->u.tex.level, surf->u.tex.first_layer,
    108          surf->u.tex.last_layer - surf->u.tex.first_layer + 1,
    109          resolve_flags);
    110 }
    111 
    112 static inline void
    113 ilo_blit_resolve_transfer(struct ilo_context *ilo,
    114                           const struct pipe_transfer *xfer)
    115 {
    116    unsigned resolve_flags = 0;
    117 
    118    if (xfer->resource->target == PIPE_BUFFER)
    119       return;
    120 
    121    if (xfer->usage & PIPE_TRANSFER_READ)
    122       resolve_flags |= ILO_TEXTURE_CPU_READ;
    123    if (xfer->usage & PIPE_TRANSFER_WRITE)
    124       resolve_flags |= ILO_TEXTURE_CPU_WRITE;
    125 
    126    ilo_blit_resolve_slices(ilo, xfer->resource, xfer->level,
    127          xfer->box.z, xfer->box.depth, resolve_flags);
    128 }
    129 
    130 static inline void
    131 ilo_blit_resolve_view(struct ilo_context *ilo,
    132                       const struct pipe_sampler_view *view)
    133 {
    134    const unsigned resolve_flags = ILO_TEXTURE_RENDER_READ;
    135    unsigned lv;
    136 
    137    if (view->texture->target == PIPE_BUFFER)
    138       return;
    139 
    140    for (lv = view->u.tex.first_level; lv <= view->u.tex.last_level; lv++) {
    141       unsigned first_slice, num_slices;
    142 
    143       if (view->texture->target == PIPE_TEXTURE_3D) {
    144          first_slice = 0;
    145          num_slices = u_minify(view->texture->depth0, lv);
    146       }
    147       else {
    148          first_slice = view->u.tex.first_layer;
    149          num_slices = view->u.tex.last_layer - view->u.tex.first_layer + 1;
    150       }
    151 
    152       ilo_blit_resolve_slices(ilo, view->texture,
    153             lv, first_slice, num_slices, resolve_flags);
    154    }
    155 }
    156 
    157 static inline void
    158 ilo_blit_resolve_framebuffer(struct ilo_context *ilo)
    159 {
    160    struct ilo_state_vector *vec = &ilo->state_vector;
    161    const struct pipe_framebuffer_state *fb = &vec->fb.state;
    162    unsigned sh, i;
    163 
    164    /* Not all bound views are sampled by the shaders.  How do we tell? */
    165    for (sh = 0; sh < ARRAY_SIZE(vec->view); sh++) {
    166       for (i = 0; i < vec->view[sh].count; i++) {
    167          if (vec->view[sh].states[i])
    168             ilo_blit_resolve_view(ilo, vec->view[sh].states[i]);
    169       }
    170    }
    171 
    172    for (i = 0; i < fb->nr_cbufs; i++) {
    173       struct pipe_surface *surf = fb->cbufs[i];
    174       if (surf)
    175          ilo_blit_resolve_surface(ilo, surf, ILO_TEXTURE_RENDER_WRITE);
    176    }
    177 
    178    if (fb->zsbuf)
    179       ilo_blit_resolve_surface(ilo, fb->zsbuf, ILO_TEXTURE_RENDER_WRITE);
    180 }
    181 
    182 void
    183 ilo_init_blit_functions(struct ilo_context *ilo);
    184 
    185 #endif /* ILO_BLIT_H */
    186