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