1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 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_blitter.h" 29 #include "util/u_surface.h" 30 31 #include "ilo_context.h" 32 #include "ilo_blitter.h" 33 34 enum ilo_blitter_pipe_op { 35 ILO_BLITTER_PIPE_BLIT, 36 ILO_BLITTER_PIPE_COPY, 37 ILO_BLITTER_PIPE_CLEAR, 38 ILO_BLITTER_PIPE_CLEAR_FB, 39 }; 40 41 static void 42 ilo_blitter_pipe_begin(struct ilo_blitter *blitter, 43 enum ilo_blitter_pipe_op op, 44 bool scissor_enable) 45 { 46 struct blitter_context *b = blitter->pipe_blitter; 47 struct ilo_state_vector *vec = &blitter->ilo->state_vector; 48 49 /* vertex states */ 50 util_blitter_save_vertex_buffer_slot(b, vec->vb.states); 51 util_blitter_save_vertex_elements(b, (void *) vec->ve); 52 util_blitter_save_vertex_shader(b, vec->vs); 53 util_blitter_save_geometry_shader(b, vec->gs); 54 util_blitter_save_so_targets(b, vec->so.count, vec->so.states); 55 util_blitter_save_rasterizer(b, (void *) vec->rasterizer); 56 57 /* fragment states */ 58 util_blitter_save_fragment_shader(b, vec->fs); 59 util_blitter_save_depth_stencil_alpha(b, (void *) vec->dsa); 60 util_blitter_save_blend(b, (void *) vec->blend); 61 util_blitter_save_sample_mask(b, vec->sample_mask); 62 util_blitter_save_stencil_ref(b, &vec->stencil_ref); 63 util_blitter_save_viewport(b, &vec->viewport.viewport0); 64 65 if (scissor_enable) 66 util_blitter_save_scissor(b, &vec->viewport.scissor0); 67 68 switch (op) { 69 case ILO_BLITTER_PIPE_BLIT: 70 case ILO_BLITTER_PIPE_COPY: 71 /* 72 * We are about to call util_blitter_blit() or 73 * util_blitter_copy_texture(). Note that util_blitter uses at most two 74 * textures. 75 */ 76 util_blitter_save_fragment_sampler_states(b, 77 2, (void **) vec->sampler[PIPE_SHADER_FRAGMENT].cso); 78 79 util_blitter_save_fragment_sampler_views(b, 80 vec->view[PIPE_SHADER_FRAGMENT].count, 81 vec->view[PIPE_SHADER_FRAGMENT].states); 82 83 util_blitter_save_framebuffer(b, &vec->fb.state); 84 85 /* resource_copy_region() or blit() does not honor render condition */ 86 util_blitter_save_render_condition(b, 87 blitter->ilo->render_condition.query, 88 blitter->ilo->render_condition.condition, 89 blitter->ilo->render_condition.mode); 90 break; 91 case ILO_BLITTER_PIPE_CLEAR: 92 /* 93 * we are about to call util_blitter_clear_render_target() or 94 * util_blitter_clear_depth_stencil() 95 */ 96 util_blitter_save_framebuffer(b, &vec->fb.state); 97 break; 98 case ILO_BLITTER_PIPE_CLEAR_FB: 99 /* we are about to call util_blitter_clear() */ 100 break; 101 default: 102 break; 103 } 104 } 105 106 static void 107 ilo_blitter_pipe_end(struct ilo_blitter *blitter) 108 { 109 } 110 111 bool 112 ilo_blitter_pipe_blit(struct ilo_blitter *blitter, 113 const struct pipe_blit_info *info) 114 { 115 struct blitter_context *b = blitter->pipe_blitter; 116 struct pipe_blit_info skip_stencil; 117 118 if (util_try_blit_via_copy_region(&blitter->ilo->base, info)) 119 return true; 120 121 if (!util_blitter_is_blit_supported(b, info)) { 122 /* try without stencil */ 123 if (info->mask & PIPE_MASK_S) { 124 skip_stencil = *info; 125 skip_stencil.mask = info->mask & ~PIPE_MASK_S; 126 127 if (util_blitter_is_blit_supported(blitter->pipe_blitter, 128 &skip_stencil)) { 129 ilo_warn("ignore stencil buffer blitting\n"); 130 info = &skip_stencil; 131 } 132 } 133 134 if (info != &skip_stencil) { 135 ilo_warn("failed to blit with pipe blitter\n"); 136 return false; 137 } 138 } 139 140 ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_BLIT, 141 info->scissor_enable); 142 util_blitter_blit(b, info); 143 ilo_blitter_pipe_end(blitter); 144 145 return true; 146 } 147 148 bool 149 ilo_blitter_pipe_copy_resource(struct ilo_blitter *blitter, 150 struct pipe_resource *dst, unsigned dst_level, 151 unsigned dst_x, unsigned dst_y, unsigned dst_z, 152 struct pipe_resource *src, unsigned src_level, 153 const struct pipe_box *src_box) 154 { 155 /* not until we allow rendertargets to be buffers */ 156 if (dst->target == PIPE_BUFFER || src->target == PIPE_BUFFER) 157 return false; 158 159 if (!util_blitter_is_copy_supported(blitter->pipe_blitter, dst, src)) 160 return false; 161 162 ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_COPY, false); 163 164 util_blitter_copy_texture(blitter->pipe_blitter, 165 dst, dst_level, dst_x, dst_y, dst_z, 166 src, src_level, src_box); 167 168 ilo_blitter_pipe_end(blitter); 169 170 return true; 171 } 172 173 bool 174 ilo_blitter_pipe_clear_rt(struct ilo_blitter *blitter, 175 struct pipe_surface *rt, 176 const union pipe_color_union *color, 177 unsigned x, unsigned y, 178 unsigned width, unsigned height) 179 { 180 ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_CLEAR, false); 181 182 util_blitter_clear_render_target(blitter->pipe_blitter, 183 rt, color, x, y, width, height); 184 185 ilo_blitter_pipe_end(blitter); 186 187 return true; 188 } 189 190 bool 191 ilo_blitter_pipe_clear_zs(struct ilo_blitter *blitter, 192 struct pipe_surface *zs, 193 unsigned clear_flags, 194 double depth, unsigned stencil, 195 unsigned x, unsigned y, 196 unsigned width, unsigned height) 197 { 198 ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_CLEAR, false); 199 200 util_blitter_clear_depth_stencil(blitter->pipe_blitter, 201 zs, clear_flags, depth, stencil, x, y, width, height); 202 203 ilo_blitter_pipe_end(blitter); 204 205 return true; 206 } 207 208 bool 209 ilo_blitter_pipe_clear_fb(struct ilo_blitter *blitter, 210 unsigned buffers, 211 const union pipe_color_union *color, 212 double depth, unsigned stencil) 213 { 214 struct ilo_state_vector *vec = &blitter->ilo->state_vector; 215 216 /* TODO we should pause/resume some queries */ 217 ilo_blitter_pipe_begin(blitter, ILO_BLITTER_PIPE_CLEAR_FB, false); 218 219 util_blitter_clear(blitter->pipe_blitter, 220 vec->fb.state.width, vec->fb.state.height, 1, 221 buffers, color, depth, stencil); 222 223 ilo_blitter_pipe_end(blitter); 224 225 return true; 226 } 227