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