u_blitter.h revision af69d88d
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 VMWARE 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 33#include "pipe/p_state.h" 34 35/* u_memory.h conflicts with st/mesa */ 36#ifndef Elements 37#define Elements(x) (sizeof(x)/sizeof((x)[0])) 38#endif 39 40 41#ifdef __cplusplus 42extern "C" { 43#endif 44 45struct pipe_context; 46 47enum blitter_attrib_type { 48 UTIL_BLITTER_ATTRIB_NONE, 49 UTIL_BLITTER_ATTRIB_COLOR, 50 UTIL_BLITTER_ATTRIB_TEXCOORD 51}; 52 53struct blitter_context 54{ 55 /** 56 * Draw a rectangle. 57 * 58 * \param x1 An X coordinate of the top-left corner. 59 * \param y1 A Y coordinate of the top-left corner. 60 * \param x2 An X coordinate of the bottom-right corner. 61 * \param y2 A Y coordinate of the bottom-right corner. 62 * \param depth A depth which the rectangle is rendered at. 63 * 64 * \param type Semantics of the attributes "attrib". 65 * If type is UTIL_BLITTER_ATTRIB_NONE, ignore them. 66 * If type is UTIL_BLITTER_ATTRIB_COLOR, the attributes 67 * make up a constant RGBA color, and should go 68 * to the GENERIC0 varying slot of a fragment shader. 69 * If type is UTIL_BLITTER_ATTRIB_TEXCOORD, {a1, a2} and 70 * {a3, a4} specify top-left and bottom-right texture 71 * coordinates of the rectangle, respectively, and should go 72 * to the GENERIC0 varying slot of a fragment shader. 73 * 74 * \param attrib See type. 75 * 76 * \note A driver may optionally override this callback to implement 77 * a specialized hardware path for drawing a rectangle, e.g. using 78 * a rectangular point sprite. 79 */ 80 void (*draw_rectangle)(struct blitter_context *blitter, 81 int x1, int y1, int x2, int y2, 82 float depth, 83 enum blitter_attrib_type type, 84 const union pipe_color_union *color); 85 86 /** 87 * Get the next surface layer for the pipe surface, i.e. make a copy 88 * of the surface and increment the first and last layer by 1. 89 * 90 * This callback is exposed, so that drivers can override it if needed. 91 */ 92 struct pipe_surface *(*get_next_surface_layer)(struct pipe_context *pipe, 93 struct pipe_surface *surf); 94 95 /* Whether the blitter is running. */ 96 boolean running; 97 98 /* Private members, really. */ 99 struct pipe_context *pipe; /**< pipe context */ 100 101 void *saved_blend_state; /**< blend state */ 102 void *saved_dsa_state; /**< depth stencil alpha state */ 103 void *saved_velem_state; /**< vertex elements state */ 104 void *saved_rs_state; /**< rasterizer state */ 105 void *saved_fs, *saved_vs, *saved_gs; /**< shaders */ 106 107 struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */ 108 struct pipe_stencil_ref saved_stencil_ref; /**< stencil ref */ 109 struct pipe_viewport_state saved_viewport; 110 struct pipe_scissor_state saved_scissor; 111 boolean is_sample_mask_saved; 112 unsigned saved_sample_mask; 113 114 unsigned saved_num_sampler_states; 115 void *saved_sampler_states[PIPE_MAX_SAMPLERS]; 116 117 unsigned saved_num_sampler_views; 118 struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS]; 119 120 unsigned vb_slot; 121 struct pipe_vertex_buffer saved_vertex_buffer; 122 123 unsigned saved_num_so_targets; 124 struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS]; 125 126 struct pipe_query *saved_render_cond_query; 127 uint saved_render_cond_mode; 128 boolean saved_render_cond_cond; 129}; 130 131/** 132 * Create a blitter context. 133 */ 134struct blitter_context *util_blitter_create(struct pipe_context *pipe); 135 136/** 137 * Destroy a blitter context. 138 */ 139void util_blitter_destroy(struct blitter_context *blitter); 140 141void util_blitter_cache_all_shaders(struct blitter_context *blitter); 142 143/** 144 * Return the pipe context associated with a blitter context. 145 */ 146static INLINE 147struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter) 148{ 149 return blitter->pipe; 150} 151 152/** 153 * Override PIPE_CAP_TEXTURE_MULTISAMPLE as reported by the driver. 154 */ 155void util_blitter_set_texture_multisample(struct blitter_context *blitter, 156 boolean supported); 157 158/* The default function to draw a rectangle. This can only be used 159 * inside of the draw_rectangle callback if the driver overrides it. */ 160void util_blitter_draw_rectangle(struct blitter_context *blitter, 161 int x1, int y1, int x2, int y2, float depth, 162 enum blitter_attrib_type type, 163 const union pipe_color_union *attrib); 164 165 166/* 167 * These states must be saved before any of the following functions are called: 168 * - vertex buffers 169 * - vertex elements 170 * - vertex shader 171 * - geometry shader (if supported) 172 * - stream output targets (if supported) 173 * - rasterizer state 174 */ 175 176/** 177 * Clear a specified set of currently bound buffers to specified values. 178 * 179 * These states must be saved in the blitter in addition to the state objects 180 * already required to be saved: 181 * - fragment shader 182 * - depth stencil alpha state 183 * - blend state 184 */ 185void util_blitter_clear(struct blitter_context *blitter, 186 unsigned width, unsigned height, unsigned num_layers, 187 unsigned clear_buffers, 188 const union pipe_color_union *color, 189 double depth, unsigned stencil); 190 191/** 192 * Check if the blitter (with the help of the driver) can blit between 193 * the two resources. 194 */ 195boolean util_blitter_is_copy_supported(struct blitter_context *blitter, 196 const struct pipe_resource *dst, 197 const struct pipe_resource *src); 198 199boolean util_blitter_is_blit_supported(struct blitter_context *blitter, 200 const struct pipe_blit_info *info); 201 202/** 203 * Copy a block of pixels from one surface to another. 204 * 205 * These states must be saved in the blitter in addition to the state objects 206 * already required to be saved: 207 * - fragment shader 208 * - depth stencil alpha state 209 * - blend state 210 * - fragment sampler states 211 * - fragment sampler textures 212 * - framebuffer state 213 * - sample mask 214 */ 215void util_blitter_copy_texture(struct blitter_context *blitter, 216 struct pipe_resource *dst, 217 unsigned dst_level, 218 unsigned dstx, unsigned dsty, unsigned dstz, 219 struct pipe_resource *src, 220 unsigned src_level, 221 const struct pipe_box *srcbox); 222 223/** 224 * This is a generic implementation of pipe->blit, which accepts 225 * sampler/surface views instead of resources. 226 * 227 * The layer and mipmap level are specified by the views. 228 * 229 * Drivers can use this to change resource properties (like format, width, 230 * height) by changing how the views interpret them, instead of changing 231 * pipe_resource directly. This is used to blit resources of formats which 232 * are not renderable. 233 * 234 * src_width0 and src_height0 are sampler_view-private properties that 235 * override pipe_resource. The blitter uses them for computation of texture 236 * coordinates. The dst dimensions are supplied through pipe_surface::width 237 * and height. 238 * 239 * The mask is a combination of the PIPE_MASK_* flags. 240 * Set to PIPE_MASK_RGBAZS if unsure. 241 */ 242void util_blitter_blit_generic(struct blitter_context *blitter, 243 struct pipe_surface *dst, 244 const struct pipe_box *dstbox, 245 struct pipe_sampler_view *src, 246 const struct pipe_box *srcbox, 247 unsigned src_width0, unsigned src_height0, 248 unsigned mask, unsigned filter, 249 const struct pipe_scissor_state *scissor); 250 251void util_blitter_blit(struct blitter_context *blitter, 252 const struct pipe_blit_info *info); 253 254/** 255 * Helper function to initialize a view for copy_texture_view. 256 * The parameters must match copy_texture_view. 257 */ 258void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, 259 struct pipe_resource *dst, 260 unsigned dstlevel, 261 unsigned dstz); 262 263/** 264 * Helper function to initialize a view for copy_texture_view. 265 * The parameters must match copy_texture_view. 266 */ 267void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ, 268 struct pipe_resource *src, 269 unsigned srclevel); 270 271/** 272 * Copy data from one buffer to another using the Stream Output functionality. 273 * 4-byte alignment is required, otherwise software fallback is used. 274 */ 275void util_blitter_copy_buffer(struct blitter_context *blitter, 276 struct pipe_resource *dst, 277 unsigned dstx, 278 struct pipe_resource *src, 279 unsigned srcx, 280 unsigned size); 281 282/** 283 * Clear the contents of a buffer using the Stream Output functionality. 284 * 4-byte alignment is required. 285 * 286 * "num_channels" can be 1, 2, 3, or 4, and specifies if the clear value is 287 * R, RG, RGB, or RGBA. 288 * 289 * For each element, only "num_channels" components of "clear_value" are 290 * copied to the buffer, then the offset is incremented by num_channels*4. 291 */ 292void util_blitter_clear_buffer(struct blitter_context *blitter, 293 struct pipe_resource *dst, 294 unsigned offset, unsigned size, 295 unsigned num_channels, 296 const union pipe_color_union *clear_value); 297 298/** 299 * Clear a region of a (color) surface to a constant value. 300 * 301 * These states must be saved in the blitter in addition to the state objects 302 * already required to be saved: 303 * - fragment shader 304 * - depth stencil alpha state 305 * - blend state 306 * - framebuffer state 307 */ 308void util_blitter_clear_render_target(struct blitter_context *blitter, 309 struct pipe_surface *dst, 310 const union pipe_color_union *color, 311 unsigned dstx, unsigned dsty, 312 unsigned width, unsigned height); 313 314/** 315 * Clear a region of a depth-stencil surface, both stencil and depth 316 * or only one of them if this is a combined depth-stencil surface. 317 * 318 * These states must be saved in the blitter in addition to the state objects 319 * already required to be saved: 320 * - fragment shader 321 * - depth stencil alpha state 322 * - blend state 323 * - framebuffer state 324 */ 325void util_blitter_clear_depth_stencil(struct blitter_context *blitter, 326 struct pipe_surface *dst, 327 unsigned clear_flags, 328 double depth, 329 unsigned stencil, 330 unsigned dstx, unsigned dsty, 331 unsigned width, unsigned height); 332 333/* The following functions are customized variants of the clear functions. 334 * Some drivers use them internally to do things like MSAA resolve 335 * and resource decompression. It usually consists of rendering a full-screen 336 * quad with a special blend or DSA state. 337 */ 338 339/* Used by r300g for depth decompression. */ 340void util_blitter_custom_clear_depth(struct blitter_context *blitter, 341 unsigned width, unsigned height, 342 double depth, void *custom_dsa); 343 344/* Used by r600g for depth decompression. */ 345void util_blitter_custom_depth_stencil(struct blitter_context *blitter, 346 struct pipe_surface *zsurf, 347 struct pipe_surface *cbsurf, 348 unsigned sample_mask, 349 void *dsa_stage, float depth); 350 351/* Used by r600g for color decompression. */ 352void util_blitter_custom_color(struct blitter_context *blitter, 353 struct pipe_surface *dstsurf, 354 void *custom_blend); 355 356/* Used by r600g for MSAA color resolve. */ 357void util_blitter_custom_resolve_color(struct blitter_context *blitter, 358 struct pipe_resource *dst, 359 unsigned dst_level, 360 unsigned dst_layer, 361 struct pipe_resource *src, 362 unsigned src_layer, 363 unsigned sampled_mask, 364 void *custom_blend, 365 enum pipe_format format); 366 367/* The functions below should be used to save currently bound constant state 368 * objects inside a driver. The objects are automatically restored at the end 369 * of the util_blitter_{clear, copy_region, fill_region} functions and then 370 * forgotten. 371 * 372 * States not listed here are not affected by util_blitter. */ 373 374static INLINE 375void util_blitter_save_blend(struct blitter_context *blitter, 376 void *state) 377{ 378 blitter->saved_blend_state = state; 379} 380 381static INLINE 382void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter, 383 void *state) 384{ 385 blitter->saved_dsa_state = state; 386} 387 388static INLINE 389void util_blitter_save_vertex_elements(struct blitter_context *blitter, 390 void *state) 391{ 392 blitter->saved_velem_state = state; 393} 394 395static INLINE 396void util_blitter_save_stencil_ref(struct blitter_context *blitter, 397 const struct pipe_stencil_ref *state) 398{ 399 blitter->saved_stencil_ref = *state; 400} 401 402static INLINE 403void util_blitter_save_rasterizer(struct blitter_context *blitter, 404 void *state) 405{ 406 blitter->saved_rs_state = state; 407} 408 409static INLINE 410void util_blitter_save_fragment_shader(struct blitter_context *blitter, 411 void *fs) 412{ 413 blitter->saved_fs = fs; 414} 415 416static INLINE 417void util_blitter_save_vertex_shader(struct blitter_context *blitter, 418 void *vs) 419{ 420 blitter->saved_vs = vs; 421} 422 423static INLINE 424void util_blitter_save_geometry_shader(struct blitter_context *blitter, 425 void *gs) 426{ 427 blitter->saved_gs = gs; 428} 429 430static INLINE 431void util_blitter_save_framebuffer(struct blitter_context *blitter, 432 const struct pipe_framebuffer_state *state) 433{ 434 blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */ 435 util_copy_framebuffer_state(&blitter->saved_fb_state, state); 436} 437 438static INLINE 439void util_blitter_save_viewport(struct blitter_context *blitter, 440 struct pipe_viewport_state *state) 441{ 442 blitter->saved_viewport = *state; 443} 444 445static INLINE 446void util_blitter_save_scissor(struct blitter_context *blitter, 447 struct pipe_scissor_state *state) 448{ 449 blitter->saved_scissor = *state; 450} 451 452static INLINE 453void util_blitter_save_fragment_sampler_states( 454 struct blitter_context *blitter, 455 unsigned num_sampler_states, 456 void **sampler_states) 457{ 458 assert(num_sampler_states <= Elements(blitter->saved_sampler_states)); 459 460 blitter->saved_num_sampler_states = num_sampler_states; 461 memcpy(blitter->saved_sampler_states, sampler_states, 462 num_sampler_states * sizeof(void *)); 463} 464 465static INLINE void 466util_blitter_save_fragment_sampler_views(struct blitter_context *blitter, 467 unsigned num_views, 468 struct pipe_sampler_view **views) 469{ 470 unsigned i; 471 assert(num_views <= Elements(blitter->saved_sampler_views)); 472 473 blitter->saved_num_sampler_views = num_views; 474 for (i = 0; i < num_views; i++) 475 pipe_sampler_view_reference(&blitter->saved_sampler_views[i], 476 views[i]); 477} 478 479static INLINE void 480util_blitter_save_vertex_buffer_slot(struct blitter_context *blitter, 481 struct pipe_vertex_buffer *vertex_buffers) 482{ 483 pipe_resource_reference(&blitter->saved_vertex_buffer.buffer, 484 vertex_buffers[blitter->vb_slot].buffer); 485 memcpy(&blitter->saved_vertex_buffer, &vertex_buffers[blitter->vb_slot], 486 sizeof(struct pipe_vertex_buffer)); 487} 488 489static INLINE void 490util_blitter_save_so_targets(struct blitter_context *blitter, 491 unsigned num_targets, 492 struct pipe_stream_output_target **targets) 493{ 494 unsigned i; 495 assert(num_targets <= Elements(blitter->saved_so_targets)); 496 497 blitter->saved_num_so_targets = num_targets; 498 for (i = 0; i < num_targets; i++) 499 pipe_so_target_reference(&blitter->saved_so_targets[i], 500 targets[i]); 501} 502 503static INLINE void 504util_blitter_save_sample_mask(struct blitter_context *blitter, 505 unsigned sample_mask) 506{ 507 blitter->is_sample_mask_saved = TRUE; 508 blitter->saved_sample_mask = sample_mask; 509} 510 511static INLINE void 512util_blitter_save_render_condition(struct blitter_context *blitter, 513 struct pipe_query *query, 514 boolean condition, 515 uint mode) 516{ 517 blitter->saved_render_cond_query = query; 518 blitter->saved_render_cond_mode = mode; 519 blitter->saved_render_cond_cond = condition; 520} 521 522#ifdef __cplusplus 523} 524#endif 525 526#endif 527