u_blitter.h revision b177e2c54c7dbec58c2547524abe89e52d458252
1/************************************************************************** 2 * 3 * Copyright 2009 Marek Olšák <maraeo@gmail.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 **************************************************************************/ 26 27#ifndef U_BLITTER_H 28#define U_BLITTER_H 29 30#include "util/u_framebuffer.h" 31#include "util/u_inlines.h" 32#include "util/u_memory.h" 33 34#include "pipe/p_state.h" 35 36 37#ifdef __cplusplus 38extern "C" { 39#endif 40 41struct pipe_context; 42 43enum blitter_attrib_type { 44 UTIL_BLITTER_ATTRIB_NONE, 45 UTIL_BLITTER_ATTRIB_COLOR, 46 UTIL_BLITTER_ATTRIB_TEXCOORD 47}; 48 49struct blitter_context 50{ 51 /** 52 * Draw a rectangle. 53 * 54 * \param x1 An X coordinate of the top-left corner. 55 * \param y1 A Y coordinate of the top-left corner. 56 * \param x2 An X coordinate of the bottom-right corner. 57 * \param y2 A Y coordinate of the bottom-right corner. 58 * \param depth A depth which the rectangle is rendered at. 59 * 60 * \param type Semantics of the attributes "attrib". 61 * If type is UTIL_BLITTER_ATTRIB_NONE, ignore them. 62 * If type is UTIL_BLITTER_ATTRIB_COLOR, the attributes 63 * make up a constant RGBA color, and should go 64 * to the GENERIC0 varying slot of a fragment shader. 65 * If type is UTIL_BLITTER_ATTRIB_TEXCOORD, {a1, a2} and 66 * {a3, a4} specify top-left and bottom-right texture 67 * coordinates of the rectangle, respectively, and should go 68 * to the GENERIC0 varying slot of a fragment shader. 69 * 70 * \param attrib See type. 71 * 72 * \note A driver may optionally override this callback to implement 73 * a specialized hardware path for drawing a rectangle, e.g. using 74 * a rectangular point sprite. 75 */ 76 void (*draw_rectangle)(struct blitter_context *blitter, 77 unsigned x1, unsigned y1, unsigned x2, unsigned y2, 78 float depth, 79 enum blitter_attrib_type type, 80 const union pipe_color_union *color); 81 82 /* Whether the blitter is running. */ 83 boolean running; 84 85 /* Private members, really. */ 86 struct pipe_context *pipe; /**< pipe context */ 87 88 void *saved_blend_state; /**< blend state */ 89 void *saved_dsa_state; /**< depth stencil alpha state */ 90 void *saved_velem_state; /**< vertex elements state */ 91 void *saved_rs_state; /**< rasterizer state */ 92 void *saved_fs, *saved_vs, *saved_gs; /**< shaders */ 93 94 struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */ 95 struct pipe_stencil_ref saved_stencil_ref; /**< stencil ref */ 96 struct pipe_viewport_state saved_viewport; 97 struct pipe_clip_state saved_clip; 98 99 int saved_num_sampler_states; 100 void *saved_sampler_states[PIPE_MAX_SAMPLERS]; 101 102 int saved_num_sampler_views; 103 struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS]; 104 105 int saved_num_vertex_buffers; 106 struct pipe_vertex_buffer saved_vertex_buffers[PIPE_MAX_ATTRIBS]; 107 108 int saved_num_so_targets; 109 struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS]; 110}; 111 112/** 113 * Create a blitter context. 114 */ 115struct blitter_context *util_blitter_create(struct pipe_context *pipe); 116 117/** 118 * Destroy a blitter context. 119 */ 120void util_blitter_destroy(struct blitter_context *blitter); 121 122/** 123 * Return the pipe context associated with a blitter context. 124 */ 125static INLINE 126struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter) 127{ 128 return blitter->pipe; 129} 130 131/* 132 * These states must be saved before any of the following functions are called: 133 * - vertex buffers 134 * - vertex elements 135 * - vertex shader 136 * - geometry shader (if supported) 137 * - stream output targets (if supported) 138 * - rasterizer state 139 */ 140 141/** 142 * Clear a specified set of currently bound buffers to specified values. 143 * 144 * These states must be saved in the blitter in addition to the state objects 145 * already required to be saved: 146 * - fragment shader 147 * - depth stencil alpha state 148 * - blend state 149 */ 150void util_blitter_clear(struct blitter_context *blitter, 151 unsigned width, unsigned height, 152 unsigned num_cbufs, 153 unsigned clear_buffers, 154 enum pipe_format cbuf_format, 155 const union pipe_color_union *color, 156 double depth, unsigned stencil); 157 158void util_blitter_clear_depth_custom(struct blitter_context *blitter, 159 unsigned width, unsigned height, 160 double depth, void *custom_dsa); 161 162/** 163 * Copy a block of pixels from one surface to another. 164 * 165 * You can copy from any color format to any other color format provided 166 * the former can be sampled from and the latter can be rendered to. Otherwise, 167 * a software fallback path is taken and both surfaces must be of the same 168 * format. 169 * 170 * The same holds for depth-stencil formats with the exception that stencil 171 * cannot be copied unless you set ignore_stencil to FALSE. In that case, 172 * a software fallback path is taken and both surfaces must be of the same 173 * format. 174 * XXX implement hw-accel stencil copy using shader stencil export. 175 * 176 * Use pipe_screen->is_format_supported to know your options. 177 * 178 * These states must be saved in the blitter in addition to the state objects 179 * already required to be saved: 180 * - fragment shader 181 * - depth stencil alpha state 182 * - blend state 183 * - fragment sampler states 184 * - fragment sampler textures 185 * - framebuffer state 186 */ 187void util_blitter_copy_texture(struct blitter_context *blitter, 188 struct pipe_resource *dst, 189 unsigned dstlevel, 190 unsigned dstx, unsigned dsty, unsigned dstz, 191 struct pipe_resource *src, 192 unsigned srclevel, 193 const struct pipe_box *srcbox, 194 boolean ignore_stencil); 195 196/** 197 * Same as util_blitter_copy_texture, but dst and src are pipe_surface and 198 * pipe_sampler_view, respectively. The mipmap level and dstz are part of 199 * the views. 200 * 201 * Drivers can use this to change resource properties (like format, width, 202 * height) by changing how the views interpret them, instead of changing 203 * pipe_resource directly. This is usually needed to accelerate copying of 204 * compressed formats. 205 * 206 * src_width0 and src_height0 are sampler_view-private properties that 207 * override pipe_resource. The blitter uses them for computation of texture 208 * coordinates. The dst dimensions are supplied through pipe_surface::width 209 * and height. 210 * 211 * NOTE: There are no checks whether the blit is actually supported. 212 */ 213void util_blitter_copy_texture_view(struct blitter_context *blitter, 214 struct pipe_surface *dst, 215 unsigned dstx, unsigned dsty, 216 struct pipe_sampler_view *src, 217 const struct pipe_box *srcbox, 218 unsigned src_width0, unsigned src_height0); 219 220/** 221 * Clear a region of a (color) surface to a constant value. 222 * 223 * These states must be saved in the blitter in addition to the state objects 224 * already required to be saved: 225 * - fragment shader 226 * - depth stencil alpha state 227 * - blend state 228 * - framebuffer state 229 */ 230void util_blitter_clear_render_target(struct blitter_context *blitter, 231 struct pipe_surface *dst, 232 const union pipe_color_union *color, 233 unsigned dstx, unsigned dsty, 234 unsigned width, unsigned height); 235 236/** 237 * Clear a region of a depth-stencil surface, both stencil and depth 238 * or only one of them if this is a combined depth-stencil surface. 239 * 240 * These states must be saved in the blitter in addition to the state objects 241 * already required to be saved: 242 * - fragment shader 243 * - depth stencil alpha state 244 * - blend state 245 * - framebuffer state 246 */ 247void util_blitter_clear_depth_stencil(struct blitter_context *blitter, 248 struct pipe_surface *dst, 249 unsigned clear_flags, 250 double depth, 251 unsigned stencil, 252 unsigned dstx, unsigned dsty, 253 unsigned width, unsigned height); 254 255void util_blitter_custom_depth_stencil(struct blitter_context *blitter, 256 struct pipe_surface *zsurf, 257 struct pipe_surface *cbsurf, 258 void *dsa_stage, float depth); 259 260/* The functions below should be used to save currently bound constant state 261 * objects inside a driver. The objects are automatically restored at the end 262 * of the util_blitter_{clear, copy_region, fill_region} functions and then 263 * forgotten. 264 * 265 * States not listed here are not affected by util_blitter. */ 266 267static INLINE 268void util_blitter_save_blend(struct blitter_context *blitter, 269 void *state) 270{ 271 blitter->saved_blend_state = state; 272} 273 274static INLINE 275void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter, 276 void *state) 277{ 278 blitter->saved_dsa_state = state; 279} 280 281static INLINE 282void util_blitter_save_vertex_elements(struct blitter_context *blitter, 283 void *state) 284{ 285 blitter->saved_velem_state = state; 286} 287 288static INLINE 289void util_blitter_save_stencil_ref(struct blitter_context *blitter, 290 const struct pipe_stencil_ref *state) 291{ 292 blitter->saved_stencil_ref = *state; 293} 294 295static INLINE 296void util_blitter_save_rasterizer(struct blitter_context *blitter, 297 void *state) 298{ 299 blitter->saved_rs_state = state; 300} 301 302static INLINE 303void util_blitter_save_fragment_shader(struct blitter_context *blitter, 304 void *fs) 305{ 306 blitter->saved_fs = fs; 307} 308 309static INLINE 310void util_blitter_save_vertex_shader(struct blitter_context *blitter, 311 void *vs) 312{ 313 blitter->saved_vs = vs; 314} 315 316static INLINE 317void util_blitter_save_geometry_shader(struct blitter_context *blitter, 318 void *gs) 319{ 320 blitter->saved_gs = gs; 321} 322 323static INLINE 324void util_blitter_save_framebuffer(struct blitter_context *blitter, 325 const struct pipe_framebuffer_state *state) 326{ 327 blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */ 328 util_copy_framebuffer_state(&blitter->saved_fb_state, state); 329} 330 331static INLINE 332void util_blitter_save_viewport(struct blitter_context *blitter, 333 struct pipe_viewport_state *state) 334{ 335 blitter->saved_viewport = *state; 336} 337 338static INLINE 339void util_blitter_save_clip(struct blitter_context *blitter, 340 struct pipe_clip_state *state) 341{ 342 blitter->saved_clip = *state; 343} 344 345static INLINE 346void util_blitter_save_fragment_sampler_states( 347 struct blitter_context *blitter, 348 int num_sampler_states, 349 void **sampler_states) 350{ 351 assert(num_sampler_states <= Elements(blitter->saved_sampler_states)); 352 353 blitter->saved_num_sampler_states = num_sampler_states; 354 memcpy(blitter->saved_sampler_states, sampler_states, 355 num_sampler_states * sizeof(void *)); 356} 357 358static INLINE void 359util_blitter_save_fragment_sampler_views(struct blitter_context *blitter, 360 int num_views, 361 struct pipe_sampler_view **views) 362{ 363 unsigned i; 364 assert(num_views <= Elements(blitter->saved_sampler_views)); 365 366 blitter->saved_num_sampler_views = num_views; 367 for (i = 0; i < num_views; i++) 368 pipe_sampler_view_reference(&blitter->saved_sampler_views[i], 369 views[i]); 370} 371 372static INLINE void 373util_blitter_save_vertex_buffers(struct blitter_context *blitter, 374 int num_vertex_buffers, 375 struct pipe_vertex_buffer *vertex_buffers) 376{ 377 assert(num_vertex_buffers <= Elements(blitter->saved_vertex_buffers)); 378 379 blitter->saved_num_vertex_buffers = 0; 380 util_copy_vertex_buffers(blitter->saved_vertex_buffers, 381 (unsigned*)&blitter->saved_num_vertex_buffers, 382 vertex_buffers, 383 num_vertex_buffers); 384} 385 386static INLINE void 387util_blitter_save_so_targets(struct blitter_context *blitter, 388 int num_targets, 389 struct pipe_stream_output_target **targets) 390{ 391 unsigned i; 392 assert(num_targets <= Elements(blitter->saved_so_targets)); 393 394 blitter->saved_num_so_targets = num_targets; 395 for (i = 0; i < num_targets; i++) 396 pipe_so_target_reference(&blitter->saved_so_targets[i], 397 targets[i]); 398} 399 400#ifdef __cplusplus 401} 402#endif 403 404#endif 405